src/share/classes/java/awt/EventQueue.java

Print this page

        

@@ -44,11 +44,12 @@
 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.locks.ReentrantLock;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import java.security.AccessControlContext;
 import java.security.ProtectionDomain;
 
 import sun.misc.SharedSecrets;

@@ -97,16 +98,11 @@
  * @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 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,11 +135,11 @@
     /*
      * 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 ReentrantLock pushPopLock;
     private final Condition pushPopCond;
 
     /*
      * Dummy runnable to wake up EDT from getNextEvent() after
      push/pop is performed

@@ -173,13 +169,13 @@
 
     /*
      * 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 volatile int waitForID;
 
-    private final String name = "AWT-EventQueue-" + nextThreadNum();
+    private final String name = "AWT-EventQueue-" + threadInitNumber.getAndIncrement();
 
     private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.EventQueue");
 
     static {
         AWTAccessor.setEventQueueAccessor(

@@ -204,11 +200,11 @@
          * 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);
+        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,12 +508,14 @@
                     return event;
                 }
                 AWTAutoShutdown.getInstance().notifyThreadFree(dispatchThread);
                 pushPopCond.await();
             } finally {
+                if(pushPopLock.isHeldByCurrentThread()) {
                 pushPopLock.unlock();
             }
+            }
         } while(true);
     }
 
     /*
      * Must be called under the lock. Doesn't call flushPendingEvents()

@@ -567,12 +565,14 @@
                 }
                 waitForID = id;
                 pushPopCond.await();
                 waitForID = 0;
             } finally {
+                if(pushPopLock.isHeldByCurrentThread()) {
                 pushPopLock.unlock();
             }
+            }
         } while(true);
     }
 
     /**
      * Returns the first event on the <code>EventQueue</code>

@@ -1028,11 +1028,11 @@
         } finally {
             pushPopLock.unlock();
         }
     }
 
-    final boolean detachDispatchThread(EventDispatchThread edt) {
+    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,11 +1047,11 @@
                  * 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()) {
+                if (!forceDetach && (peekEvent() != null) || !SunToolkit.isPostEventQueueEmpty()) {
                     return false;
                 }
                 dispatchThread = null;
             }
             AWTAutoShutdown.getInstance().notifyThreadFree(edt);