changeset 7216:25072b5b7e78

8031477: [macosx] Loading AWT native library fails 8002191: AWT-Shutdown thread does not start with the AppletSecurity on Linux 8031032: SQE test failures after JDK-8025010 was fixed Reviewed-by: serb, ddehaven
author pchelko
date Wed, 09 Apr 2014 15:27:54 +0100
parents 5b9b47ebf559
children 9448fff93286
files src/macosx/classes/sun/font/CFontManager.java src/macosx/classes/sun/lwawt/LWToolkit.java src/macosx/native/sun/awt/awt.m src/macosx/native/sun/osxapp/ThreadUtilities.h src/macosx/native/sun/osxapp/ThreadUtilities.m src/share/classes/java/awt/EventQueue.java src/share/classes/sun/awt/AWTAutoShutdown.java src/share/classes/sun/awt/SunToolkit.java src/share/classes/sun/font/CreatedFontTracker.java src/share/classes/sun/font/SunFontManager.java src/share/classes/sun/java2d/Disposer.java src/share/classes/sun/java2d/opengl/OGLRenderQueue.java src/share/classes/sun/misc/ThreadGroupUtils.java src/solaris/classes/sun/awt/X11/XToolkit.java src/solaris/classes/sun/awt/X11GraphicsDevice.java src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java src/windows/classes/sun/awt/windows/WToolkit.java src/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java
diffstat 18 files changed, 201 insertions(+), 180 deletions(-) [+]
line wrap: on
line diff
--- a/src/macosx/classes/sun/font/CFontManager.java	Mon Mar 10 18:40:38 2014 +0000
+++ b/src/macosx/classes/sun/font/CFontManager.java	Wed Apr 09 15:27:54 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, 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
@@ -27,6 +27,8 @@
 
 import java.awt.*;
 import java.io.File;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Hashtable;
@@ -38,6 +40,7 @@
 
 import sun.awt.FontConfiguration;
 import sun.awt.HeadlessToolkit;
+import sun.misc.ThreadGroupUtils;
 import sun.lwawt.macosx.*;
 
 public class CFontManager extends SunFontManager {
@@ -218,21 +221,17 @@
                 java.security.AccessController.doPrivileged(
                         new java.security.PrivilegedAction<Object>() {
                             public Object run() {
-                                /* The thread must be a member of a thread group
-                                 * which will not get GCed before VM exit.
-                                 * Make its parent the top-level thread group.
-                                 */
-                                ThreadGroup tg =
-                                    Thread.currentThread().getThreadGroup();
-                                for (ThreadGroup tgn = tg;
-                                tgn != null;
-                                tg = tgn, tgn = tg.getParent());
-                                fileCloser = new Thread(tg, fileCloserRunnable);
-                                fileCloser.setContextClassLoader(null);
-                                Runtime.getRuntime().addShutdownHook(fileCloser);
-                                return null;
-                            }
-                        });
+                            /* The thread must be a member of a thread group
+                             * which will not get GCed before VM exit.
+                             * Make its parent the top-level thread group.
+                             */
+                            ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
+                            fileCloser = new Thread(rootTG, fileCloserRunnable);
+                            fileCloser.setContextClassLoader(null);
+                            Runtime.getRuntime().addShutdownHook(fileCloser);
+                            return null;
+                        }
+		    });
                 }
             }
         }
--- a/src/macosx/classes/sun/lwawt/LWToolkit.java	Mon Mar 10 18:40:38 2014 +0000
+++ b/src/macosx/classes/sun/lwawt/LWToolkit.java	Wed Apr 09 15:27:54 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, 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
@@ -38,6 +38,7 @@
 import sun.awt.*;
 import sun.lwawt.macosx.*;
 import sun.print.*;
+import sun.misc.ThreadGroupUtils;
 
 public abstract class LWToolkit extends SunToolkit implements Runnable {
 
@@ -66,22 +67,16 @@
     protected final void init() {
         AWTAutoShutdown.notifyToolkitThreadBusy();
 
-        ThreadGroup mainTG = AccessController.doPrivileged(
+        ThreadGroup rootTG = AccessController.doPrivileged(
             new PrivilegedAction<ThreadGroup>() {
                 public ThreadGroup run() {
-                    ThreadGroup currentTG = Thread.currentThread().getThreadGroup();
-                    ThreadGroup parentTG = currentTG.getParent();
-                    while (parentTG != null) {
-                        currentTG = parentTG;
-                        parentTG = currentTG.getParent();
-                    }
-                    return currentTG;
-                }
-            }
+		    return ThreadGroupUtils.getRootThreadGroup();
+		}
+	    }
         );
 
         Runtime.getRuntime().addShutdownHook(
-            new Thread(mainTG, new Runnable() {
+            new Thread(rootTG, new Runnable() {
                 public void run() {
                     shutdown();
                     waitForRunState(STATE_CLEANUP);
@@ -89,7 +84,7 @@
             })
         );
 
-        Thread toolkitThread = new Thread(mainTG, this, "AWT-LW");
+        Thread toolkitThread = new Thread(rootTG, this, "AWT-LW");
         toolkitThread.setDaemon(true);
         toolkitThread.setPriority(Thread.NORM_PRIORITY + 1);
         toolkitThread.start();
--- a/src/macosx/native/sun/awt/awt.m	Mon Mar 10 18:40:38 2014 +0000
+++ b/src/macosx/native/sun/awt/awt.m	Wed Apr 09 15:27:54 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, 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
@@ -433,10 +433,10 @@
     }
 
     JNIEnv* env = [ThreadUtilities getJNIEnvUncached];
-    jclass jc_SunToolkit = (*env)->FindClass(env, "sun/awt/SunToolkit");
-    jmethodID sjm_getRootThreadGroup = (*env)->GetStaticMethodID(env, jc_SunToolkit, "getRootThreadGroup", "()Ljava/lang/ThreadGroup;");
-    jobject rootThreadGroup = (*env)->CallStaticObjectMethod(env, jc_SunToolkit, sjm_getRootThreadGroup);
-    appkitThreadGroup = (*env)->NewGlobalRef(env, rootThreadGroup);
+    jclass jc_ThreadGroupUtils = (*env)->FindClass(env, "sun/misc/ThreadGroupUtils");
+    jmethodID sjm_getRootThreadGroup = (*env)->GetStaticMethodID(env, jc_ThreadGroupUtils, "getRootThreadGroup", "()Ljava/lang/ThreadGroup;");
+    jobject rootThreadGroup = (*env)->CallStaticObjectMethod(env, jc_ThreadGroupUtils, sjm_getRootThreadGroup);
+    [ThreadUtilities setAppkitThreadGroup:(*env)->NewGlobalRef(env, rootThreadGroup)];
     // The current thread was attached in getJNIEnvUncached.
     // Detach it back. It will be reattached later if needed with a proper TG
     [ThreadUtilities detachCurrentThread];
--- a/src/macosx/native/sun/osxapp/ThreadUtilities.h	Mon Mar 10 18:40:38 2014 +0000
+++ b/src/macosx/native/sun/osxapp/ThreadUtilities.h	Wed Apr 09 15:27:54 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, 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
@@ -122,15 +122,13 @@
 #endif /* AWT_THREAD_ASSERTS */
 // --------------------------------------------------------------------------
 
-// Set from JNI_Onload
-extern jobject appkitThreadGroup;
-
 __attribute__((visibility("default")))
 @interface ThreadUtilities { }
 
 + (JNIEnv*)getJNIEnv;
 + (JNIEnv*)getJNIEnvUncached;
 + (void)detachCurrentThread;
++ (void)setAppkitThreadGroup:(jobject)group;
 
 //Wrappers for the corresponding JNFRunLoop methods with a check for main thread
 + (void)performOnMainThreadWaiting:(BOOL)wait block:(void (^)())block;
--- a/src/macosx/native/sun/osxapp/ThreadUtilities.m	Mon Mar 10 18:40:38 2014 +0000
+++ b/src/macosx/native/sun/osxapp/ThreadUtilities.m	Wed Apr 09 15:27:54 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, 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
@@ -33,18 +33,18 @@
 // The following must be named "jvm", as there are extern references to it in AWT
 JavaVM *jvm = NULL;
 static JNIEnv *appKitEnv = NULL;
-jobject appkitThreadGroup = NULL;
+static jobject appkitThreadGroup = NULL;
 
 inline void attachCurrentThread(void** env) {
-    JavaVMAttachArgs args;
-    args.version = JNI_VERSION_1_2;
-    args.name = NULL; // Set from LWCToolkit
     if ([NSThread isMainThread]) {
+        JavaVMAttachArgs args;
+        args.version = JNI_VERSION_1_4;
+        args.name = "AppKit Thread";
         args.group = appkitThreadGroup;
+        (*jvm)->AttachCurrentThreadAsDaemon(jvm, env, &args);
     } else {
-        args.group = NULL;
+        (*jvm)->AttachCurrentThreadAsDaemon(jvm, env, NULL);
     }
-    (*jvm)->AttachCurrentThreadAsDaemon(jvm, env, &args);
 }
 
 @implementation ThreadUtilities
@@ -67,6 +67,10 @@
     (*jvm)->DetachCurrentThread(jvm);
 }
 
++ (void)setAppkitThreadGroup:(jobject)group {
+    appkitThreadGroup = group;
+}
+
 + (void)performOnMainThreadWaiting:(BOOL)wait block:(void (^)())block {
     if ([NSThread isMainThread] && wait == YES) {
         block(); 
--- a/src/share/classes/java/awt/EventQueue.java	Mon Mar 10 18:40:38 2014 +0000
+++ b/src/share/classes/java/awt/EventQueue.java	Wed Apr 09 15:27:54 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2014, 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
@@ -1043,11 +1043,11 @@
                             t.setContextClassLoader(classLoader);
                             t.setPriority(Thread.NORM_PRIORITY + 1);
                             t.setDaemon(false);
+                            AWTAutoShutdown.getInstance().notifyThreadBusy(t);
                             return t;
                         }
                     }
                 );
-                AWTAutoShutdown.getInstance().notifyThreadBusy(dispatchThread);
                 dispatchThread.start();
             }
         } finally {
--- a/src/share/classes/sun/awt/AWTAutoShutdown.java	Mon Mar 10 18:40:38 2014 +0000
+++ b/src/share/classes/sun/awt/AWTAutoShutdown.java	Wed Apr 09 15:27:54 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2014, 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
@@ -28,11 +28,12 @@
 import java.awt.AWTEvent;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.IdentityHashMap;
 import java.util.Map;
+
 import sun.util.logging.PlatformLogger;
+import sun.misc.ThreadGroupUtils;
 
 /**
  * This class is to let AWT shutdown automatically when a user is done
@@ -214,7 +215,12 @@
         synchronized (activationLock) {
             synchronized (mainLock) {
                 if (!isReadyToShutdown() && blockerThread == null) {
-                    activateBlockerThread();
+                    AccessController.doPrivileged(new PrivilegedAction<Void>() {
+			    public Void run() {
+				activateBlockerThread();
+				return null;
+			    }
+                    });
                 } else {
                     mainLock.notifyAll();
                     timeoutPassed = false;
@@ -330,14 +336,8 @@
      * the new blocker thread starts.
      */
     private void activateBlockerThread() {
-        final Thread thread = new Thread(SunToolkit.getRootThreadGroup(), this, "AWT-Shutdown");
-        AccessController.doPrivileged(new PrivilegedAction<Void>() {
-            @Override
-            public Void run() {
-                thread.setContextClassLoader(null);
-                return null;
-            }
-        });
+        Thread thread = new Thread(ThreadGroupUtils.getRootThreadGroup(), this, "AWT-Shutdown");
+        thread.setContextClassLoader(null);
         thread.setDaemon(false);
         blockerThread = thread;
         thread.start();
--- a/src/share/classes/sun/awt/SunToolkit.java	Mon Mar 10 18:40:38 2014 +0000
+++ b/src/share/classes/sun/awt/SunToolkit.java	Wed Apr 09 15:27:54 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, 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
@@ -1127,20 +1127,6 @@
         return startupLocale;
     }
 
-    protected static ThreadGroup getRootThreadGroup() {
-        return AccessController.doPrivileged(new PrivilegedAction<ThreadGroup>() {
-            @Override
-            public ThreadGroup run() {
-                ThreadGroup currentTG = Thread.currentThread().getThreadGroup();
-                ThreadGroup parentTG = currentTG.getParent();
-                while (parentTG != null) {
-                    currentTG = parentTG;
-                    parentTG = currentTG.getParent();
-                }
-                return currentTG;
-            }
-        });
-    }
     /**
      * Returns the default keyboard locale of the underlying operating system
      */
--- a/src/share/classes/sun/font/CreatedFontTracker.java	Mon Mar 10 18:40:38 2014 +0000
+++ b/src/share/classes/sun/font/CreatedFontTracker.java	Wed Apr 09 15:27:54 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2014, 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
@@ -27,12 +27,15 @@
 
 import java.io.File;
 import java.io.OutputStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 
 import sun.awt.AppContext;
+import sun.misc.ThreadGroupUtils;
 
 public class CreatedFontTracker {
 
@@ -112,28 +115,23 @@
         static void init() {
             if (t == null) {
                 // Add a shutdown hook to remove the temp file.
-                java.security.AccessController.doPrivileged(
-                   new java.security.PrivilegedAction() {
-                      public Object run() {
-                          /* The thread must be a member of a thread group
-                           * which will not get GCed before VM exit.
-                           * Make its parent the top-level thread group.
-                           */
-                          ThreadGroup tg =
-                              Thread.currentThread().getThreadGroup();
-                          for (ThreadGroup tgn = tg;
-                               tgn != null;
-                               tg = tgn, tgn = tg.getParent());
-                          t = new Thread(tg, new Runnable() {
-                              public void run() {
-                                  runHooks();
-                              }
-                          });
-                          t.setContextClassLoader(null);
-                          Runtime.getRuntime().addShutdownHook(t);
-                          return null;
-                      }
-                   });
+                AccessController.doPrivileged(new PrivilegedAction<Void>() {
+			public Void run() {
+                            /* The thread must be a member of a thread group
+                             * which will not get GCed before VM exit.
+                             * Make its parent the top-level thread group.
+                             */
+                            ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
+			    t = new Thread(rootTG, new Runnable() {
+				    public void run() {
+					runHooks();
+				    }
+				});
+                            t.setContextClassLoader(null);
+                            Runtime.getRuntime().addShutdownHook(t);
+                            return null;
+			}
+		    });
             }
         }
 
--- a/src/share/classes/sun/font/SunFontManager.java	Mon Mar 10 18:40:38 2014 +0000
+++ b/src/share/classes/sun/font/SunFontManager.java	Wed Apr 09 15:27:54 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2014, 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
@@ -52,6 +52,7 @@
 import sun.awt.AppContext;
 import sun.awt.FontConfiguration;
 import sun.awt.SunToolkit;
+import sun.misc.ThreadGroupUtils;
 import sun.java2d.FontSupport;
 import sun.util.logging.PlatformLogger;
 
@@ -2521,24 +2522,19 @@
                           });
                       }
                     };
-                    java.security.AccessController.doPrivileged(
-                       new java.security.PrivilegedAction() {
-                          public Object run() {
-                              /* The thread must be a member of a thread group
-                               * which will not get GCed before VM exit.
-                               * Make its parent the top-level thread group.
-                               */
-                              ThreadGroup tg =
-                                  Thread.currentThread().getThreadGroup();
-                              for (ThreadGroup tgn = tg;
-                                   tgn != null;
-                                   tg = tgn, tgn = tg.getParent());
-                              fileCloser = new Thread(tg, fileCloserRunnable);
-                              fileCloser.setContextClassLoader(null);
-                              Runtime.getRuntime().addShutdownHook(fileCloser);
-                              return null;
-                          }
-                    });
+                    AccessController.doPrivileged(new PrivilegedAction<Void>() {
+			    public Void run() {
+                                /* The thread must be a member of a thread group
+                                 * which will not get GCed before VM exit.
+                                 * Make its parent the top-level thread group.
+                                 */
+                                ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
+                                fileCloser = new Thread(rootTG, fileCloserRunnable);
+                                fileCloser.setContextClassLoader(null);
+                                Runtime.getRuntime().addShutdownHook(fileCloser);
+                                return null;
+			    }
+			});
                 }
             }
         }
--- a/src/share/classes/sun/java2d/Disposer.java	Mon Mar 10 18:40:38 2014 +0000
+++ b/src/share/classes/sun/java2d/Disposer.java	Wed Apr 09 15:27:54 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2014, 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
@@ -25,10 +25,14 @@
 
 package sun.java2d;
 
+import sun.misc.ThreadGroupUtils;
+
 import java.lang.ref.Reference;
 import java.lang.ref.ReferenceQueue;
 import java.lang.ref.PhantomReference;
 import java.lang.ref.WeakReference;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.ArrayList;
 import java.util.Hashtable;
 
@@ -72,18 +76,14 @@
         }
         disposerInstance = new Disposer();
         java.security.AccessController.doPrivileged(
-            new java.security.PrivilegedAction() {
-                public Object run() {
+            new java.security.PrivilegedAction<Void>() {
+                public Void run() {
                     /* The thread must be a member of a thread group
                      * which will not get GCed before VM exit.
                      * Make its parent the top-level thread group.
                      */
-                    ThreadGroup tg = Thread.currentThread().getThreadGroup();
-                    for (ThreadGroup tgn = tg;
-                         tgn != null;
-                         tg = tgn, tgn = tg.getParent());
-                    Thread t =
-                        new Thread(tg, disposerInstance, "Java2D Disposer");
+                    ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
+                    Thread t = new Thread(rootTG, disposerInstance, "Java2D Disposer");
                     t.setContextClassLoader(null);
                     t.setDaemon(true);
                     t.setPriority(Thread.MAX_PRIORITY);
--- a/src/share/classes/sun/java2d/opengl/OGLRenderQueue.java	Mon Mar 10 18:40:38 2014 +0000
+++ b/src/share/classes/sun/java2d/opengl/OGLRenderQueue.java	Wed Apr 09 15:27:54 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2014, 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
@@ -25,6 +25,7 @@
 
 package sun.java2d.opengl;
 
+import sun.misc.ThreadGroupUtils;
 import sun.java2d.pipe.RenderBuffer;
 import sun.java2d.pipe.RenderQueue;
 import static sun.java2d.pipe.BufferedOpCodes.*;
@@ -49,11 +50,7 @@
          */
         flusher = AccessController.doPrivileged(new PrivilegedAction<QueueFlusher>() {
             public QueueFlusher run() {
-                ThreadGroup rootThreadGroup = Thread.currentThread().getThreadGroup();
-                while (rootThreadGroup.getParent() != null) {
-                    rootThreadGroup = rootThreadGroup.getParent();
-                }
-                return new QueueFlusher(rootThreadGroup);
+		return new QueueFlusher(ThreadGroupUtils.getRootThreadGroup());
             }
         });
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/misc/ThreadGroupUtils.java	Wed Apr 09 15:27:54 2014 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2014, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.misc;
+
+/**
+ * A utility class needed to access the root {@code ThreadGroup}
+ *
+ * The class should not depend on any others, because it' called from JNI_OnLoad of the AWT
+ * native library. Triggering class loading could could lead to a deadlock.
+ */
+public final class ThreadGroupUtils {
+
+    private ThreadGroupUtils() {
+        // Avoid instantiation
+    }
+
+    /**
+     * Returns a root thread group.
+     * Should be called with {@link sun.security.util.SecurityConstants#MODIFY_THREADGROUP_PERMISSION}
+     *
+     * @return a root {@code ThreadGroup}
+     */
+    public static ThreadGroup getRootThreadGroup() {
+        ThreadGroup currentTG = Thread.currentThread().getThreadGroup();
+        ThreadGroup parentTG = currentTG.getParent();
+        while (parentTG != null) {
+            currentTG = parentTG;
+            parentTG = currentTG.getParent();
+        }
+        return currentTG;
+    }
+}
--- a/src/solaris/classes/sun/awt/X11/XToolkit.java	Mon Mar 10 18:40:38 2014 +0000
+++ b/src/solaris/classes/sun/awt/X11/XToolkit.java	Wed Apr 09 15:27:54 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2014, 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
@@ -48,7 +48,7 @@
 import javax.swing.UIDefaults;
 import sun.awt.*;
 import sun.font.FontConfigManager;
-import sun.misc.PerformanceLogger;
+import sun.misc.*;
 import sun.print.PrintJob2D;
 import sun.security.action.GetPropertyAction;
 import sun.security.action.GetBooleanAction;
@@ -311,7 +311,7 @@
         }
         PrivilegedAction<Void> a = new PrivilegedAction<Void>() {
             public Void run() {
-                Thread shutdownThread = new Thread(getRootThreadGroup(), "XToolkt-Shutdown-Thread") {
+                Thread shutdownThread = new Thread(ThreadGroupUtils.getRootThreadGroup(), "XToolkt-Shutdown-Thread") {
                         public void run() {
                             XSystemTrayPeer peer = XSystemTrayPeer.getPeerInstance();
                             if (peer != null) {
@@ -376,7 +376,7 @@
 
             PrivilegedAction<Thread> action = new PrivilegedAction() {
                 public Thread run() {
-                    Thread thread = new Thread(getRootThreadGroup(), XToolkit.this, "AWT-XAWT");
+                    Thread thread = new Thread(ThreadGroupUtils.getRootThreadGroup(), XToolkit.this, "AWT-XAWT");
                     thread.setContextClassLoader(null);
                     thread.setPriority(Thread.NORM_PRIORITY + 1);
                     thread.setDaemon(true);
--- a/src/solaris/classes/sun/awt/X11GraphicsDevice.java	Mon Mar 10 18:40:38 2014 +0000
+++ b/src/solaris/classes/sun/awt/X11GraphicsDevice.java	Wed Apr 09 15:27:54 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, 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
@@ -42,6 +42,8 @@
 import sun.java2d.xr.XRGraphicsConfig;
 import sun.java2d.loops.SurfaceType;
 
+import sun.misc.ThreadGroupUtils;
+
 /**
  * This is an implementation of a GraphicsDevice object for a single
  * X11 screen.
@@ -425,12 +427,7 @@
             shutdownHookRegistered = true;
             PrivilegedAction<Void> a = new PrivilegedAction<Void>() {
                 public Void run() {
-                    ThreadGroup mainTG = Thread.currentThread().getThreadGroup();
-                    ThreadGroup parentTG = mainTG.getParent();
-                    while (parentTG != null) {
-                        mainTG = parentTG;
-                        parentTG = mainTG.getParent();
-                    }
+		    ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
                     Runnable r = new Runnable() {
                             public void run() {
                                 Window old = getFullScreenWindow();
@@ -440,11 +437,11 @@
                                 }
                             }
                         };
-                    Thread t = new Thread(mainTG, r,"Display-Change-Shutdown-Thread-"+screen);
-                    t.setContextClassLoader(null);
-                    Runtime.getRuntime().addShutdownHook(t);
-                    return null;
-                }
+		    Thread t = new Thread(rootTG, r,"Display-Change-Shutdown-Thread-"+screen);
+		    t.setContextClassLoader(null);
+		    Runtime.getRuntime().addShutdownHook(t);
+		    return null;
+		}
             };
             AccessController.doPrivileged(a);
         }
--- a/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java	Mon Mar 10 18:40:38 2014 +0000
+++ b/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java	Wed Apr 09 15:27:54 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, 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
@@ -41,6 +41,7 @@
 
 import static sun.awt.shell.Win32ShellFolder2.*;
 import sun.awt.OSInfo;
+import sun.misc.ThreadGroupUtils;
 
 // NOTE: This class supersedes Win32ShellFolderManager, which was removed
 //       from distribution after version 1.4.2.
@@ -513,15 +514,12 @@
                              * which will not get GCed before VM exit.
                              * Make its parent the top-level thread group.
                              */
-                            ThreadGroup tg = Thread.currentThread().getThreadGroup();
-                            for (ThreadGroup tgn = tg;
-                                 tgn != null;
-                                 tg = tgn, tgn = tg.getParent());
-                            Thread thread = new Thread(tg, comRun, "Swing-Shell");
+                            ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
+                            Thread thread = new Thread(rootTG, comRun, "Swing-Shell");
                             thread.setDaemon(true);
                             return thread;
                         }
-                    }
+		    }
                 );
             return comThread;
         }
--- a/src/windows/classes/sun/awt/windows/WToolkit.java	Mon Mar 10 18:40:38 2014 +0000
+++ b/src/windows/classes/sun/awt/windows/WToolkit.java	Wed Apr 09 15:27:54 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2014, 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
@@ -38,6 +38,7 @@
 import java.security.PrivilegedAction;
 import sun.awt.AWTAutoShutdown;
 import sun.awt.SunToolkit;
+import sun.misc.ThreadGroupUtils;
 import sun.awt.Win32GraphicsDevice;
 import sun.awt.Win32GraphicsEnvironment;
 import sun.java2d.d3d.D3DRenderQueue;
@@ -233,7 +234,11 @@
         AWTAutoShutdown.notifyToolkitThreadBusy();
 
         // Find a root TG and attach Appkit thread to it
-        ThreadGroup rootTG = getRootThreadGroup();
+        ThreadGroup rootTG = AccessController.doPrivileged(new PrivilegedAction<ThreadGroup>() {
+		public ThreadGroup run() {
+		    return ThreadGroupUtils.getRootThreadGroup();
+		}
+	    });
         if (!startToolkitThread(this, rootTG)) {
             Thread toolkitThread = new Thread(rootTG, this, "AWT-Windows");
             toolkitThread.setDaemon(true);
@@ -263,9 +268,9 @@
     }
 
     private final void registerShutdownHook() {
-        AccessController.doPrivileged(new PrivilegedAction() {
-            public Object run() {
-                Thread shutdown = new Thread(getRootThreadGroup(), new Runnable() {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
+                Thread shutdown = new Thread(ThreadGroupUtils.getRootThreadGroup(), new Runnable() {
                     public void run() {
                         shutdown();
                     }
--- a/src/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java	Mon Mar 10 18:40:38 2014 +0000
+++ b/src/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java	Wed Apr 09 15:27:54 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2014, 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
@@ -36,8 +36,9 @@
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
 import java.util.HashMap;
-import sun.awt.SunToolkit;
+
 import sun.awt.AWTAccessor;
+import sun.misc.ThreadGroupUtils;
 import sun.awt.Win32GraphicsConfig;
 import sun.awt.windows.WComponentPeer;
 import sun.java2d.InvalidPipeException;
@@ -91,17 +92,11 @@
 
     public D3DScreenUpdateManager() {
         done = false;
-        AccessController.doPrivileged(
-            new PrivilegedAction() {
-                public Object run() {
-                    ThreadGroup currentTG =
-                        Thread.currentThread().getThreadGroup();
-                    ThreadGroup parentTG = currentTG.getParent();
-                    while (parentTG != null) {
-                        currentTG = parentTG;
-                        parentTG = currentTG.getParent();
-                    }
-                    Thread shutdown = new Thread(currentTG, new Runnable() {
+         AccessController.doPrivileged(
+            new PrivilegedAction<Void>() {
+                public Void run() {
+                    ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
+                    Thread shutdown = new Thread(rootTG, new Runnable() {
                             public void run() {
                                 done = true;
                                 wakeUpUpdateThread();
@@ -354,15 +349,13 @@
      */
     private synchronized void startUpdateThread() {
         if (screenUpdater == null) {
-            screenUpdater = (Thread)java.security.AccessController.doPrivileged(
-                new java.security.PrivilegedAction() {
-                    public Object run() {
-                        ThreadGroup tg =
-                            Thread.currentThread().getThreadGroup();
-                        for (ThreadGroup tgn = tg;
-                             tgn != null; tg = tgn, tgn = tg.getParent());
-                        Thread t = new Thread(tg, D3DScreenUpdateManager.this,
-                                              "D3D Screen Updater");
+            screenUpdater = AccessController.doPrivileged(
+                new PrivilegedAction<Thread>() {
+                    public Thread run() {
+                        ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
+                        Thread t = new Thread(rootTG,
+                                D3DScreenUpdateManager.this,
+                                "D3D Screen Updater");
                         // REMIND: should it be higher?
                         t.setPriority(Thread.NORM_PRIORITY + 2);
                         t.setDaemon(true);