changeset 422:2e8ca9a18288

6623943: javax.swing.TimerQueue's thread occasionally fails to start Reviewed-by: alexp
author idk
date Mon, 23 Jun 2008 15:21:37 -0400
parents 8dfe14917105
children d5c1a46c3dad 02b79f1c8c17
files src/share/classes/javax/swing/JApplet.java src/share/classes/javax/swing/TimerQueue.java
diffstat 2 files changed, 35 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/javax/swing/JApplet.java	Wed Sep 22 09:57:07 2010 -0700
+++ b/src/share/classes/javax/swing/JApplet.java	Mon Jun 23 15:21:37 2008 -0400
@@ -131,10 +131,7 @@
         // 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
--- a/src/share/classes/javax/swing/TimerQueue.java	Wed Sep 22 09:57:07 2010 -0700
+++ b/src/share/classes/javax/swing/TimerQueue.java	Mon Jun 23 15:21:37 2008 -0400
@@ -30,6 +30,7 @@
 
 
 import java.util.concurrent.*;
+import java.util.concurrent.locks.*;
 import java.util.concurrent.atomic.AtomicLong;
 import sun.awt.AppContext;
 
@@ -48,7 +49,8 @@
     private static final Object sharedInstanceKey = new Object(); // TimerQueue.sharedInstanceKey
 
     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)
@@ -65,7 +67,8 @@
         super();
         queue = new DelayQueue<DelayedTimer>();
         // Now start the TimerQueue thread.
-        start();
+        runningLock = new ReentrantLock();
+        startIfNeeded();
     }
 
 
@@ -83,33 +86,30 @@
     }
 
 
-    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 {
@@ -160,6 +160,7 @@
 
 
     public void run() {
+        runningLock.lock();
         try {
             while (running) {
                 try {
@@ -191,14 +192,14 @@
             }
         }
         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();
         }
     }