src/share/classes/java/awt/EventQueue.java
Print this page
*** 44,54 ****
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.security.AccessControlContext;
import java.security.ProtectionDomain;
import sun.misc.SharedSecrets;
--- 44,55 ----
import sun.awt.SunToolkit;
import sun.awt.EventQueueItem;
import sun.awt.AWTAccessor;
import java.util.concurrent.locks.Condition;
! import java.util.concurrent.locks.ReentrantLock;
! import java.util.concurrent.atomic.AtomicInteger;
import java.security.AccessControlContext;
import java.security.ProtectionDomain;
import sun.misc.SharedSecrets;
*** 97,112 ****
* @author David Mendenhall
*
* @since 1.1
*/
public class EventQueue {
!
! // From Thread.java
! private static int threadInitNumber;
! private static synchronized int nextThreadNum() {
! return threadInitNumber++;
! }
private static final int LOW_PRIORITY = 0;
private static final int NORM_PRIORITY = 1;
private static final int HIGH_PRIORITY = 2;
private static final int ULTIMATE_PRIORITY = 3;
--- 98,108 ----
* @author David Mendenhall
*
* @since 1.1
*/
public class EventQueue {
! private static final AtomicInteger threadInitNumber = new AtomicInteger(0);
private static final int LOW_PRIORITY = 0;
private static final int NORM_PRIORITY = 1;
private static final int HIGH_PRIORITY = 2;
private static final int ULTIMATE_PRIORITY = 3;
*** 139,149 ****
/*
* A single lock to synchronize the push()/pop() and related operations with
* all the EventQueues from the AppContext. Synchronization on any particular
* event queue(s) is not enough: we should lock the whole stack.
*/
! private final Lock pushPopLock;
private final Condition pushPopCond;
/*
* Dummy runnable to wake up EDT from getNextEvent() after
push/pop is performed
--- 135,145 ----
/*
* A single lock to synchronize the push()/pop() and related operations with
* all the EventQueues from the AppContext. Synchronization on any particular
* event queue(s) is not enough: we should lock the whole stack.
*/
! private final ReentrantLock pushPopLock;
private final Condition pushPopCond;
/*
* Dummy runnable to wake up EDT from getNextEvent() after
push/pop is performed
*** 173,185 ****
/*
* Non-zero if a thread is waiting in getNextEvent(int) for an event of
* a particular ID to be posted to the queue.
*/
! private int waitForID;
! private final String name = "AWT-EventQueue-" + nextThreadNum();
private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.EventQueue");
static {
AWTAccessor.setEventQueueAccessor(
--- 169,181 ----
/*
* Non-zero if a thread is waiting in getNextEvent(int) for an event of
* a particular ID to be posted to the queue.
*/
! private volatile int waitForID;
! private final String name = "AWT-EventQueue-" + threadInitNumber.getAndIncrement();
private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.EventQueue");
static {
AWTAccessor.setEventQueueAccessor(
*** 204,214 ****
* SunToolkit.createNewAppContext() the started dispatch thread
* may call AppContext.getAppContext() before createNewAppContext()
* completes thus causing mess in thread group to appcontext mapping.
*/
! pushPopLock = (Lock)AppContext.getAppContext().get(AppContext.EVENT_QUEUE_LOCK_KEY);
pushPopCond = (Condition)AppContext.getAppContext().get(AppContext.EVENT_QUEUE_COND_KEY);
}
/**
* Posts a 1.1-style event to the <code>EventQueue</code>.
--- 200,210 ----
* SunToolkit.createNewAppContext() the started dispatch thread
* may call AppContext.getAppContext() before createNewAppContext()
* completes thus causing mess in thread group to appcontext mapping.
*/
! pushPopLock = (ReentrantLock)AppContext.getAppContext().get(AppContext.EVENT_QUEUE_LOCK_KEY);
pushPopCond = (Condition)AppContext.getAppContext().get(AppContext.EVENT_QUEUE_COND_KEY);
}
/**
* Posts a 1.1-style event to the <code>EventQueue</code>.
*** 512,523 ****
--- 508,524 ----
return event;
}
AWTAutoShutdown.getInstance().notifyThreadFree(dispatchThread);
pushPopCond.await();
} finally {
+ // In case the current Thread has been stopped,
+ // re-acquiring the lock fails, and unlocking it would
+ // cause an IllegalMonitorStateException to be thrown.
+ if(pushPopLock.isHeldByCurrentThread()) {
pushPopLock.unlock();
}
+ }
} while(true);
}
/*
* Must be called under the lock. Doesn't call flushPendingEvents()
*** 567,578 ****
--- 568,584 ----
}
waitForID = id;
pushPopCond.await();
waitForID = 0;
} finally {
+ // In case the current Thread has been stopped,
+ // re-acquiring the lock fails, and unlocking it would
+ // cause an IllegalMonitorStateException to be thrown.
+ if(pushPopLock.isHeldByCurrentThread()) {
pushPopLock.unlock();
}
+ }
} while(true);
}
/**
* Returns the first event on the <code>EventQueue</code>
*** 1028,1038 ****
} 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
--- 1034,1044 ----
} finally {
pushPopLock.unlock();
}
}
! 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
*** 1047,1057 ****
* 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);
--- 1053,1063 ----
* 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);