mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-06 08:28:27 +00:00
6623943: javax.swing.TimerQueue's thread occasionally fails to start
Reviewed-by: alexp
This commit is contained in:
parent
7690c18be2
commit
762ea5875b
@ -131,10 +131,7 @@ public class JApplet extends Applet implements Accessible,
|
||||
// Check the timerQ and restart if necessary.
|
||||
TimerQueue q = TimerQueue.sharedInstance();
|
||||
if(q != null) {
|
||||
synchronized(q) {
|
||||
if(!q.running)
|
||||
q.start();
|
||||
}
|
||||
q.startIfNeeded();
|
||||
}
|
||||
|
||||
/* Workaround for bug 4155072. The shared double buffer image
|
||||
|
||||
@ -31,6 +31,7 @@ package javax.swing;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.locks.*;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import sun.awt.AppContext;
|
||||
|
||||
@ -52,7 +53,8 @@ class TimerQueue implements Runnable
|
||||
new StringBuffer("TimerQueue.expiredTimersKey");
|
||||
|
||||
private final DelayQueue<DelayedTimer> queue;
|
||||
volatile boolean running;
|
||||
private volatile boolean running;
|
||||
private final Lock runningLock;
|
||||
|
||||
/* Lock object used in place of class object for synchronization.
|
||||
* (4187686)
|
||||
@ -69,7 +71,8 @@ class TimerQueue implements Runnable
|
||||
super();
|
||||
queue = new DelayQueue<DelayedTimer>();
|
||||
// Now start the TimerQueue thread.
|
||||
start();
|
||||
runningLock = new ReentrantLock();
|
||||
startIfNeeded();
|
||||
}
|
||||
|
||||
|
||||
@ -87,33 +90,30 @@ class TimerQueue implements Runnable
|
||||
}
|
||||
|
||||
|
||||
synchronized void start() {
|
||||
if (running) {
|
||||
throw new RuntimeException("Can't start a TimerQueue " +
|
||||
"that is already running");
|
||||
}
|
||||
else {
|
||||
final ThreadGroup threadGroup =
|
||||
AppContext.getAppContext().getThreadGroup();
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction() {
|
||||
public Object run() {
|
||||
Thread timerThread = new Thread(threadGroup, TimerQueue.this,
|
||||
"TimerQueue");
|
||||
timerThread.setDaemon(true);
|
||||
timerThread.setPriority(Thread.NORM_PRIORITY);
|
||||
timerThread.start();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
running = true;
|
||||
void startIfNeeded() {
|
||||
if (! running) {
|
||||
runningLock.lock();
|
||||
try {
|
||||
final ThreadGroup threadGroup =
|
||||
AppContext.getAppContext().getThreadGroup();
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction() {
|
||||
public Object run() {
|
||||
Thread timerThread = new Thread(threadGroup, TimerQueue.this,
|
||||
"TimerQueue");
|
||||
timerThread.setDaemon(true);
|
||||
timerThread.setPriority(Thread.NORM_PRIORITY);
|
||||
timerThread.start();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
running = true;
|
||||
} finally {
|
||||
runningLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
synchronized void stop() {
|
||||
running = false;
|
||||
}
|
||||
|
||||
void addTimer(Timer timer, long delayMillis) {
|
||||
timer.getLock().lock();
|
||||
try {
|
||||
@ -164,6 +164,7 @@ class TimerQueue implements Runnable
|
||||
|
||||
|
||||
public void run() {
|
||||
runningLock.lock();
|
||||
try {
|
||||
while (running) {
|
||||
try {
|
||||
@ -195,14 +196,14 @@ class TimerQueue implements Runnable
|
||||
}
|
||||
}
|
||||
catch (ThreadDeath td) {
|
||||
synchronized (this) {
|
||||
running = false;
|
||||
// Mark all the timers we contain as not being queued.
|
||||
for (DelayedTimer delayedTimer : queue) {
|
||||
delayedTimer.getTimer().cancelEvent();
|
||||
}
|
||||
throw td;
|
||||
// Mark all the timers we contain as not being queued.
|
||||
for (DelayedTimer delayedTimer : queue) {
|
||||
delayedTimer.getTimer().cancelEvent();
|
||||
}
|
||||
throw td;
|
||||
} finally {
|
||||
running = false;
|
||||
runningLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user