Mercurial > hg > jdk9-shenandoah > jdk
changeset 11779:db8698ee7e77
8027771: Enhance thread contexts
Reviewed-by: anthony, serb
line wrap: on
line diff
--- a/src/java.desktop/macosx/classes/com/apple/laf/AquaFileSystemModel.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaFileSystemModel.java Fri Apr 03 17:17:36 2015 +0300 @@ -25,15 +25,16 @@ package com.apple.laf; + import java.beans.*; import java.io.File; import java.util.*; - import javax.swing.*; import javax.swing.event.ListDataEvent; import javax.swing.filechooser.FileSystemView; import javax.swing.table.AbstractTableModel; +import sun.misc.ManagedLocalsThread; /** * NavServices-like implementation of a file Table * @@ -42,7 +43,7 @@ @SuppressWarnings("serial") // Superclass is not serializable across versions class AquaFileSystemModel extends AbstractTableModel implements PropertyChangeListener { private final JTable fFileList; - private LoadFilesThread loadThread = null; + private FilesLoader filesLoader = null; private Vector<File> files = null; JFileChooser filechooser = null; @@ -141,9 +142,9 @@ public void runWhenDone(final Runnable runnable){ synchronized (fileCacheLock) { - if (loadThread != null) { - if (loadThread.isAlive()) { - loadThread.queuedTasks.add(runnable); + if (filesLoader != null) { + if (filesLoader.loadThread.isAlive()) { + filesLoader.queuedTasks.add(runnable); return; } } @@ -160,9 +161,9 @@ return; } - if (loadThread != null) { + if (filesLoader != null) { // interrupt - loadThread.interrupt(); + filesLoader.loadThread.interrupt(); } fetchID++; @@ -173,8 +174,7 @@ fileCache = new Vector<SortableFile>(50); } - loadThread = new LoadFilesThread(currentDirectory, fetchID); - loadThread.start(); + filesLoader = new FilesLoader(currentDirectory, fetchID); } public int getColumnCount() { @@ -373,17 +373,25 @@ } } - class LoadFilesThread extends Thread { - Vector<Runnable> queuedTasks = new Vector<Runnable>(); + class FilesLoader implements Runnable { + Vector<Runnable> queuedTasks = new Vector<>(); File currentDirectory = null; int fid; + Thread loadThread; - public LoadFilesThread(final File currentDirectory, final int fid) { - super("Aqua L&F File Loading Thread"); + public FilesLoader(final File currentDirectory, final int fid) { this.currentDirectory = currentDirectory; this.fid = fid; + String name = "Aqua L&F File Loading Thread"; + if (System.getSecurityManager() == null) { + this.loadThread = new Thread(FilesLoader.this, name); + } else { + this.loadThread = new ManagedLocalsThread(FilesLoader.this, name); + } + this.loadThread.start(); } + @Override public void run() { final Vector<DoChangeContents> runnables = new Vector<DoChangeContents>(10); final FileSystemView fileSystem = filechooser.getFileSystemView(); @@ -415,7 +423,7 @@ runnables.addElement(runnable); SwingUtilities.invokeLater(runnable); chunk = new Vector<SortableFile>(10); - if (isInterrupted()) { + if (loadThread.isInterrupted()) { // interrupted, cancel all runnables cancelRunnables(runnables); return;
--- a/src/java.desktop/macosx/classes/sun/font/CFontManager.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/macosx/classes/sun/font/CFontManager.java Fri Apr 03 17:17:36 2015 +0300 @@ -42,6 +42,7 @@ import sun.awt.HeadlessToolkit; import sun.awt.util.ThreadGroupUtils; import sun.lwawt.macosx.*; +import sun.misc.InnocuousThread; public final class CFontManager extends SunFontManager { private static Hashtable<String, Font2D> genericFonts = new Hashtable<String, Font2D>(); @@ -211,14 +212,18 @@ }); } }; - AccessController.doPrivileged( - (PrivilegedAction<Void>) () -> { - /* 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); + AccessController.doPrivileged((PrivilegedAction<Void>) () -> { + if (System.getSecurityManager() == 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); + } else { + /* InnocuousThread is a member of a correct TG by default */ + fileCloser = new InnocuousThread(fileCloserRunnable); + } fileCloser.setContextClassLoader(null); Runtime.getRuntime().addShutdownHook(fileCloser); return null;
--- a/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java Fri Apr 03 17:17:36 2015 +0300 @@ -35,6 +35,7 @@ import java.util.*; import sun.awt.*; +import sun.misc.InnocuousThread; import sun.print.*; import sun.awt.util.ThreadGroupUtils; @@ -71,22 +72,32 @@ */ protected final void init() { AWTAutoShutdown.notifyToolkitThreadBusy(); - - ThreadGroup rootTG = AccessController.doPrivileged( - (PrivilegedAction<ThreadGroup>) ThreadGroupUtils::getRootThreadGroup); - - Runtime.getRuntime().addShutdownHook( - new Thread(rootTG, () -> { + AccessController.doPrivileged((PrivilegedAction<Void>) () -> { + Runnable shutdownRunnable = () -> { shutdown(); waitForRunState(STATE_CLEANUP); - }) - ); + }; + Thread shutdown; + if (System.getSecurityManager() == null) { + shutdown = new Thread(ThreadGroupUtils.getRootThreadGroup(), shutdownRunnable); + } else { + shutdown = new InnocuousThread(shutdownRunnable); + } + shutdown.setContextClassLoader(null); + Runtime.getRuntime().addShutdownHook(shutdown); - Thread toolkitThread = new Thread(rootTG, this, "AWT-LW"); - toolkitThread.setDaemon(true); - toolkitThread.setPriority(Thread.NORM_PRIORITY + 1); - toolkitThread.start(); - + String name = "AWT-LW"; + Thread toolkitThread; + if (System.getSecurityManager() == null) { + toolkitThread = new Thread(ThreadGroupUtils.getRootThreadGroup(), LWToolkit.this, name); + } else { + toolkitThread = new InnocuousThread(LWToolkit.this, name); + } + toolkitThread.setDaemon(true); + toolkitThread.setPriority(Thread.NORM_PRIORITY + 1); + toolkitThread.start(); + return null; + }); waitForRunState(STATE_MESSAGELOOP); }
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java Fri Apr 03 17:17:36 2015 +0300 @@ -31,7 +31,6 @@ import java.awt.dnd.*; import java.awt.event.*; import java.awt.image.*; -import java.awt.peer.*; import javax.swing.*; import javax.swing.text.*; @@ -44,6 +43,7 @@ import sun.lwawt.LWComponentPeer; import sun.lwawt.LWWindowPeer; import sun.lwawt.PlatformWindow; +import sun.misc.ManagedLocalsThread; public final class CDragSourceContextPeer extends SunDragSourceContextPeer { @@ -164,28 +164,29 @@ // are posted during dragging by native event handlers. try { - Thread dragThread = new Thread() { - public void run() { - final long nativeDragSource = getNativeContext(); - try { - doDragging(nativeDragSource); - } catch (Exception e) { - e.printStackTrace(); - } finally { - releaseNativeDragSource(nativeDragSource); - fDragImage = null; - if (fDragCImage != null) { - fDragCImage.dispose(); - fDragCImage = null; - } + Runnable dragRunnable = () -> { + final long nativeDragSource = getNativeContext(); + try { + doDragging(nativeDragSource); + } catch (Exception e) { + e.printStackTrace(); + } finally { + releaseNativeDragSource(nativeDragSource); + fDragImage = null; + if (fDragCImage != null) { + fDragCImage.dispose(); + fDragCImage = null; } } }; - + Thread dragThread; + if (System.getSecurityManager() == null) { + dragThread = new Thread(dragRunnable); + } else { + dragThread = new ManagedLocalsThread(dragRunnable); + } dragThread.start(); - } - - catch (Exception e) { + } catch (Exception e) { final long nativeDragSource = getNativeContext(); setNativeContext(0); releaseNativeDragSource(nativeDragSource);
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CFileDialog.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CFileDialog.java Fri Apr 03 17:17:36 2015 +0300 @@ -37,6 +37,7 @@ import sun.awt.CausedFocusEvent.Cause; import sun.awt.AWTAccessor; import sun.java2d.pipe.Region; +import sun.misc.ManagedLocalsThread; import sun.security.action.GetBooleanAction; class CFileDialog implements FileDialogPeer { @@ -119,7 +120,11 @@ if (visible) { // Java2 Dialog class requires peer to run code in a separate thread // and handles keeping the call modal - new Thread(new Task()).start(); // invokes my 'run' method, below... + if (System.getSecurityManager() == null) { + new Thread(new Task()).start(); + } else { + new ManagedLocalsThread(new Task()).start(); + } } // We hide ourself before "show" returns - setVisible(false) // doesn't apply
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterDialogPeer.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterDialogPeer.java Fri Apr 03 17:17:36 2015 +0300 @@ -29,6 +29,7 @@ import java.awt.dnd.*; import sun.lwawt.*; +import sun.misc.ManagedLocalsThread; public class CPrinterDialogPeer extends LWWindowPeer { static { @@ -53,13 +54,16 @@ public void setVisible(boolean visible) { if (visible) { - new Thread(new Runnable() { - public void run() { - CPrinterDialog printerDialog = (CPrinterDialog)fTarget; - printerDialog.setRetVal(printerDialog.showDialog()); - printerDialog.setVisible(false); - } - }).start(); + Runnable task = () -> { + CPrinterDialog printerDialog = (CPrinterDialog)fTarget; + printerDialog.setRetVal(printerDialog.showDialog()); + printerDialog.setVisible(false); + }; + if (System.getSecurityManager() == null) { + new Thread(task).start(); + } else { + new ManagedLocalsThread(task).start(); + } } }
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java Fri Apr 03 17:17:36 2015 +0300 @@ -39,6 +39,7 @@ import javax.print.attribute.standard.PageRanges; import sun.java2d.*; +import sun.misc.ManagedLocalsThread; import sun.print.*; public final class CPrinterJob extends RasterPrinterJob { @@ -731,9 +732,12 @@ // upcall from native private static void detachPrintLoop(final long target, final long arg) { - new Thread() { public void run() { - _safePrintLoop(target, arg); - }}.start(); + Runnable task = () -> _safePrintLoop(target, arg); + if (System.getSecurityManager() == null) { + new Thread(task).start(); + } else { + new ManagedLocalsThread(task).start(); + } } private static native void _safePrintLoop(long target, long arg);
--- a/src/java.desktop/share/classes/com/sun/imageio/stream/StreamCloser.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/share/classes/com/sun/imageio/stream/StreamCloser.java Fri Apr 03 17:17:36 2015 +0300 @@ -25,7 +25,12 @@ package com.sun.imageio.stream; +import sun.awt.util.ThreadGroupUtils; +import sun.misc.InnocuousThread; + import java.io.IOException; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.Set; import java.util.WeakHashMap; import javax.imageio.stream.ImageInputStream; @@ -81,27 +86,25 @@ } }; - 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()); - streamCloser = new Thread(tg, streamCloserRunnable); - /* Set context class loader to null in order to avoid - * keeping a strong reference to an application classloader. - */ - streamCloser.setContextClassLoader(null); - Runtime.getRuntime().addShutdownHook(streamCloser); - return null; - } - }); + AccessController.doPrivileged((PrivilegedAction<Object>) () -> { + if (System.getSecurityManager() == 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 tg = ThreadGroupUtils.getRootThreadGroup(); + streamCloser = new Thread(tg, streamCloserRunnable); + } else { + /* InnocuousThread is a member of a correct TG by default */ + streamCloser = new InnocuousThread(streamCloserRunnable); + } + /* Set context class loader to null in order to avoid + * keeping a strong reference to an application classloader. + */ + streamCloser.setContextClassLoader(null); + Runtime.getRuntime().addShutdownHook(streamCloser); + return null; + }); } } }
--- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java Fri Apr 03 17:17:36 2015 +0300 @@ -64,6 +64,7 @@ import sun.awt.OSInfo; import sun.awt.shell.ShellFolder; import sun.font.FontUtilities; +import sun.misc.ManagedLocalsThread; import sun.security.action.GetPropertyAction; import sun.swing.DefaultLayoutStyle; @@ -2037,7 +2038,11 @@ if (audioRunnable != null) { // Runnable appears to block until completed playing, hence // start up another thread to handle playing. - new Thread(audioRunnable).start(); + if (System.getSecurityManager() == null) { + new Thread(audioRunnable).start(); + } else { + new ManagedLocalsThread(audioRunnable).start(); + } } } }
--- a/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java Fri Apr 03 17:17:36 2015 +0300 @@ -25,6 +25,9 @@ package com.sun.media.sound; +import sun.misc.InnocuousThread; +import sun.misc.ManagedLocalsThread; + import java.io.BufferedInputStream; import java.io.InputStream; import java.io.File; @@ -144,7 +147,13 @@ final String threadName, final boolean isDaemon, final int priority, final boolean doStart) { - Thread thread = new Thread(runnable); + Thread thread; + if (System.getSecurityManager() == null) { + thread = new Thread(runnable); + } else { + thread = new ManagedLocalsThread(runnable); + } + if (threadName != null) { thread.setName(threadName); }
--- a/src/java.desktop/share/classes/com/sun/media/sound/SoftAudioPusher.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/share/classes/com/sun/media/sound/SoftAudioPusher.java Fri Apr 03 17:17:36 2015 +0300 @@ -24,6 +24,8 @@ */ package com.sun.media.sound; +import sun.misc.ManagedLocalsThread; + import java.io.IOException; import javax.sound.sampled.AudioInputStream; @@ -53,7 +55,11 @@ if (active) return; active = true; - audiothread = new Thread(this); + if (System.getSecurityManager() == null) { + audiothread = new Thread(this); + } else { + audiothread = new ManagedLocalsThread(this); + } audiothread.setDaemon(true); audiothread.setPriority(Thread.MAX_PRIORITY); audiothread.start();
--- a/src/java.desktop/share/classes/com/sun/media/sound/SoftJitterCorrector.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/share/classes/com/sun/media/sound/SoftJitterCorrector.java Fri Apr 03 17:17:36 2015 +0300 @@ -24,13 +24,14 @@ */ package com.sun.media.sound; +import sun.misc.ManagedLocalsThread; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; -import javax.sound.sampled.AudioFormat; -import javax.sound.sampled.AudioInputStream; - /** * A jitter corrector to be used with SoftAudioPusher. * @@ -215,7 +216,11 @@ } }; - thread = new Thread(runnable); + if (System.getSecurityManager() == null) { + thread = new Thread(runnable); + } else { + thread = new ManagedLocalsThread(runnable); + } thread.setDaemon(true); thread.setPriority(Thread.MAX_PRIORITY); thread.start();
--- a/src/java.desktop/share/classes/com/sun/media/sound/SoftSynthesizer.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/share/classes/com/sun/media/sound/SoftSynthesizer.java Fri Apr 03 17:17:36 2015 +0300 @@ -25,6 +25,8 @@ package com.sun.media.sound; +import sun.misc.ManagedLocalsThread; + import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; @@ -139,7 +141,11 @@ pusher = null; jitter_stream = null; sourceDataLine = null; - new Thread(runnable).start(); + if (System.getSecurityManager() == null) { + new Thread(runnable).start(); + } else { + new ManagedLocalsThread(runnable).start(); + } } return len; }
--- a/src/java.desktop/share/classes/java/awt/EventDispatchThread.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/share/classes/java/awt/EventDispatchThread.java Fri Apr 03 17:17:36 2015 +0300 @@ -30,6 +30,8 @@ import java.awt.event.WindowEvent; import java.util.ArrayList; + +import sun.misc.ManagedLocalsThread; import sun.util.logging.PlatformLogger; import sun.awt.dnd.SunDragSourceContextPeer; @@ -53,7 +55,7 @@ * * @since 1.1 */ -class EventDispatchThread extends Thread { +class EventDispatchThread extends ManagedLocalsThread { private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.EventDispatchThread"); @@ -65,7 +67,7 @@ private ArrayList<EventFilter> eventFilters = new ArrayList<EventFilter>(); EventDispatchThread(ThreadGroup group, String name, EventQueue queue) { - super(group, name); + super(group, null, name); setEventQueue(queue); }
--- a/src/java.desktop/share/classes/java/awt/image/renderable/RenderableImageProducer.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/share/classes/java/awt/image/renderable/RenderableImageProducer.java Fri Apr 03 17:17:36 2015 +0300 @@ -34,10 +34,11 @@ **********************************************************************/ package java.awt.image.renderable; -import java.awt.color.ColorSpace; + +import sun.misc.ManagedLocalsThread; + import java.awt.image.ColorModel; import java.awt.image.DataBuffer; -import java.awt.image.DirectColorModel; import java.awt.image.ImageConsumer; import java.awt.image.ImageProducer; import java.awt.image.Raster; @@ -135,7 +136,13 @@ public synchronized void startProduction(ImageConsumer ic) { addConsumer(ic); // Need to build a runnable object for the Thread. - Thread thread = new Thread(this, "RenderableImageProducer Thread"); + String name = "RenderableImageProducer Thread"; + Thread thread; + if (System.getSecurityManager() == null) { + thread = new Thread(this, name); + } else { + thread = new ManagedLocalsThread(this); + } thread.start(); }
--- a/src/java.desktop/share/classes/javax/swing/JTable.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/share/classes/javax/swing/JTable.java Fri Apr 03 17:17:36 2015 +0300 @@ -53,6 +53,8 @@ import javax.print.attribute.*; import javax.print.PrintService; + +import sun.misc.ManagedLocalsThread; import sun.reflect.misc.ReflectUtil; import sun.swing.SwingUtilities2; @@ -6384,25 +6386,28 @@ // this runnable will be used to do the printing // (and save any throwables) on another thread - Runnable runnable = new Runnable() { - public void run() { - try { - // do the printing - job.print(copyAttr); - } catch (Throwable t) { - // save any Throwable to be rethrown - synchronized(lock) { - printError = t; - } - } finally { - // we're finished - hide the dialog - printingStatus.dispose(); - } + Runnable runnable = () -> { + try { + // do the printing + job.print(copyAttr); + } catch (Throwable t) { + // save any Throwable to be rethrown + synchronized(lock) { + printError = t; + } + } finally { + // we're finished - hide the dialog + printingStatus.dispose(); } }; // start printing on another thread - Thread th = new Thread(runnable); + Thread th; + if (System.getSecurityManager() == null) { + th = new Thread(runnable); + } else { + th = new ManagedLocalsThread(runnable); + } th.start(); printingStatus.showModal(true);
--- a/src/java.desktop/share/classes/javax/swing/TimerQueue.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/share/classes/javax/swing/TimerQueue.java Fri Apr 03 17:17:36 2015 +0300 @@ -29,12 +29,14 @@ +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.*; import java.util.concurrent.*; import java.util.concurrent.locks.*; import java.util.concurrent.atomic.AtomicLong; import sun.awt.AppContext; - +import sun.misc.InnocuousThread; /** @@ -94,18 +96,19 @@ if (! running) { runningLock.lock(); try { - final ThreadGroup threadGroup = - AppContext.getAppContext().getThreadGroup(); - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Object>() { - public Object run() { - Thread timerThread = new Thread(threadGroup, TimerQueue.this, - "TimerQueue"); - timerThread.setDaemon(true); - timerThread.setPriority(Thread.NORM_PRIORITY); - timerThread.start(); - return null; + final ThreadGroup threadGroup = AppContext.getAppContext().getThreadGroup(); + AccessController.doPrivileged((PrivilegedAction<Object>) () -> { + String name = "TimerQueue"; + Thread timerThread; + if (System.getSecurityManager() == null) { + timerThread = new Thread(threadGroup, TimerQueue.this, name); + } else { + timerThread = new InnocuousThread(threadGroup, TimerQueue.this, name); } + timerThread.setDaemon(true); + timerThread.setPriority(Thread.NORM_PRIORITY); + timerThread.start(); + return null; }); running = true; } finally {
--- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java Fri Apr 03 17:17:36 2015 +0300 @@ -25,15 +25,19 @@ package javax.swing.plaf.basic; -import java.io.File; -import java.util.*; -import java.util.concurrent.Callable; +import sun.awt.shell.ShellFolder; +import sun.misc.ManagedLocalsThread; + import javax.swing.*; -import javax.swing.filechooser.*; -import javax.swing.event.*; -import java.beans.*; - -import sun.awt.shell.ShellFolder; +import javax.swing.event.ListDataEvent; +import javax.swing.filechooser.FileSystemView; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.io.File; +import java.util.List; +import java.util.Vector; +import java.util.concurrent.Callable; /** * Basic implementation of a file list. @@ -46,7 +50,7 @@ private JFileChooser filechooser = null; // PENDING(jeff) pick the size more sensibly private Vector<File> fileCache = new Vector<File>(50); - private LoadFilesThread loadThread = null; + private FilesLoader filesLoader = null; private Vector<File> files = null; private Vector<File> directories = null; private int fetchID = 0; @@ -91,10 +95,10 @@ * This method is used to interrupt file loading thread. */ public void invalidateFileCache() { - if (loadThread != null) { - loadThread.interrupt(); - loadThread.cancelRunnables(); - loadThread = null; + if (filesLoader != null) { + filesLoader.loadThread.interrupt(); + filesLoader.cancelRunnables(); + filesLoader = null; } } @@ -149,15 +153,14 @@ if (currentDirectory == null) { return; } - if (loadThread != null) { - loadThread.interrupt(); - loadThread.cancelRunnables(); + if (filesLoader != null) { + filesLoader.loadThread.interrupt(); + filesLoader.cancelRunnables(); } setBusy(true, ++fetchID); - loadThread = new LoadFilesThread(currentDirectory, fetchID); - loadThread.start(); + filesLoader = new FilesLoader(currentDirectory, fetchID); } /** @@ -251,17 +254,25 @@ } - class LoadFilesThread extends Thread { + class FilesLoader implements Runnable { File currentDirectory = null; int fid; Vector<DoChangeContents> runnables = new Vector<DoChangeContents>(10); + final Thread loadThread; - public LoadFilesThread(File currentDirectory, int fid) { - super("Basic L&F File Loading Thread"); + public FilesLoader(File currentDirectory, int fid) { this.currentDirectory = currentDirectory; this.fid = fid; + String name = "Basic L&F File Loading Thread"; + if (System.getSecurityManager() == null) { + this.loadThread = new Thread(this, name); + } else { + this.loadThread = new ManagedLocalsThread(this, name); + } + this.loadThread.start(); } + @Override public void run() { run0(); setBusy(false, fid); @@ -270,13 +281,13 @@ public void run0() { FileSystemView fileSystem = filechooser.getFileSystemView(); - if (isInterrupted()) { + if (loadThread.isInterrupted()) { return; } File[] list = fileSystem.getFiles(currentDirectory, filechooser.isFileHidingEnabled()); - if (isInterrupted()) { + if (loadThread.isInterrupted()) { return; } @@ -296,7 +307,7 @@ newFiles.addElement(file); } - if (isInterrupted()) { + if (loadThread.isInterrupted()) { return; } } @@ -333,7 +344,7 @@ } if (start >= 0 && end > start && newFileCache.subList(end, newSize).equals(fileCache.subList(start, oldSize))) { - if (isInterrupted()) { + if (loadThread.isInterrupted()) { return null; } return new DoChangeContents(newFileCache.subList(start, end), start, null, 0, fid); @@ -351,14 +362,14 @@ } if (start >= 0 && end > start && fileCache.subList(end, oldSize).equals(newFileCache.subList(start, newSize))) { - if (isInterrupted()) { + if (loadThread.isInterrupted()) { return null; } return new DoChangeContents(null, 0, new Vector<>(fileCache.subList(start, end)), start, fid); } } if (!fileCache.equals(newFileCache)) { - if (isInterrupted()) { + if (loadThread.isInterrupted()) { cancelRunnables(runnables); } return new DoChangeContents(newFileCache, 0, fileCache, 0, fid);
--- a/src/java.desktop/share/classes/javax/swing/text/JTextComponent.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/share/classes/javax/swing/text/JTextComponent.java Fri Apr 03 17:17:36 2015 +0300 @@ -68,6 +68,7 @@ import sun.awt.AppContext; +import sun.misc.ManagedLocalsThread; import sun.swing.PrintingStatus; import sun.swing.SwingUtilities2; import sun.swing.text.TextComponentPrintable; @@ -2363,7 +2364,11 @@ runnablePrinting.run(); } else { if (isEventDispatchThread) { - (new Thread(runnablePrinting)).start(); + if (System.getSecurityManager() == null) { + new Thread(runnablePrinting).start(); + } else { + new ManagedLocalsThread(runnablePrinting).start(); + } printingStatus.showModal(true); } else { printingStatus.showModal(false);
--- a/src/java.desktop/share/classes/javax/swing/text/LayoutQueue.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/share/classes/javax/swing/text/LayoutQueue.java Fri Apr 03 17:17:36 2015 +0300 @@ -26,6 +26,7 @@ import java.util.Vector; import sun.awt.AppContext; +import sun.misc.ManagedLocalsThread; /** * A queue of text layout tasks. @@ -80,7 +81,22 @@ */ public synchronized void addTask(Runnable task) { if (worker == null) { - worker = new LayoutThread(); + Runnable workerRunnable = () -> { + Runnable work; + do { + work = waitForWork(); + if (work != null) { + work.run(); + } + } while (work != null); + }; + String name = "text-layout"; + if (System.getSecurityManager() == null) { + worker = new Thread(workerRunnable, name); + } else { + worker = new ManagedLocalsThread(workerRunnable, name); + } + worker.setPriority(Thread.MIN_PRIORITY); worker.start(); } tasks.addElement(task); @@ -102,28 +118,4 @@ tasks.removeElementAt(0); return work; } - - /** - * low priority thread to perform layout work forever - */ - class LayoutThread extends Thread { - - LayoutThread() { - super("text-layout"); - setPriority(Thread.MIN_PRIORITY); - } - - public void run() { - Runnable work; - do { - work = waitForWork(); - if (work != null) { - work.run(); - } - } while (work != null); - } - - - } - }
--- a/src/java.desktop/share/classes/sun/applet/AppletClassLoader.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/share/classes/sun/applet/AppletClassLoader.java Fri Apr 03 17:17:36 2015 +0300 @@ -52,6 +52,7 @@ import sun.awt.AppContext; import sun.awt.SunToolkit; import sun.misc.IOUtils; +import sun.misc.ManagedLocalsThread; import sun.net.www.ParseUtil; import sun.security.util.SecurityConstants; @@ -855,13 +856,13 @@ * this operation to complete before continuing, wait for the notifyAll() * operation on the syncObject to occur. */ -class AppContextCreator extends Thread { +class AppContextCreator extends ManagedLocalsThread { Object syncObject = new Object(); AppContext appContext = null; volatile boolean created = false; AppContextCreator(ThreadGroup group) { - super(group, "AppContextCreator"); + super(group, null, "AppContextCreator"); } public void run() {
--- a/src/java.desktop/share/classes/sun/applet/AppletPanel.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/share/classes/sun/applet/AppletPanel.java Fri Apr 03 17:17:36 2015 +0300 @@ -42,6 +42,7 @@ import sun.awt.AppContext; import sun.awt.EmbeddedFrame; import sun.awt.SunToolkit; +import sun.misc.ManagedLocalsThread; import sun.misc.MessageUtils; import sun.misc.PerformanceLogger; import sun.misc.Queue; @@ -176,8 +177,7 @@ ThreadGroup appletGroup = loader.getThreadGroup(); - - handler = new Thread(appletGroup, this, "thread " + nm); + handler = new ManagedLocalsThread(appletGroup, this, "thread " + nm); // set the context class loader for this thread AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override @@ -410,7 +410,7 @@ if (loaderThread == null) { // REMIND: do we want a name? //System.out.println("------------------- loading applet"); - setLoaderThread(new Thread(this)); + setLoaderThread(new ManagedLocalsThread(this)); loaderThread.start(); // we get to go to sleep while this runs loaderThread.join();
--- a/src/java.desktop/share/classes/sun/applet/AppletViewer.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/share/classes/sun/applet/AppletViewer.java Fri Apr 03 17:17:36 2015 +0300 @@ -38,6 +38,7 @@ import java.security.PrivilegedAction; import sun.awt.SunToolkit; import sun.awt.AppContext; +import sun.misc.ManagedLocalsThread; /** * A frame to show the applet tag in. @@ -853,7 +854,7 @@ // final AppletPanel p = panel; - new Thread(new Runnable() + new ManagedLocalsThread(new Runnable() { @Override public void run() @@ -889,7 +890,7 @@ // spawn a new thread to avoid blocking the event queue // when calling appletShutdown. // - new Thread(new Runnable() + new ManagedLocalsThread(new Runnable() { @Override public void run()
--- a/src/java.desktop/share/classes/sun/awt/AWTAutoShutdown.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/share/classes/sun/awt/AWTAutoShutdown.java Fri Apr 03 17:17:36 2015 +0300 @@ -34,6 +34,7 @@ import java.util.Map; import java.util.Set; +import sun.misc.InnocuousThread; import sun.util.logging.PlatformLogger; import sun.awt.util.ThreadGroupUtils; @@ -340,7 +341,13 @@ * Must be called with {@link sun.security.util.SecurityConstants#MODIFY_THREADGROUP_PERMISSION} */ private void activateBlockerThread() { - Thread thread = new Thread(ThreadGroupUtils.getRootThreadGroup(), this, "AWT-Shutdown"); + Thread thread; + String name = "AWT-Shutdown"; + if (System.getSecurityManager() == null) { + thread = new Thread(ThreadGroupUtils.getRootThreadGroup(), this, name); + } else { + thread = new InnocuousThread(this, name); + } thread.setContextClassLoader(null); thread.setDaemon(false); blockerThread = thread;
--- a/src/java.desktop/share/classes/sun/awt/AppContext.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/share/classes/sun/awt/AppContext.java Fri Apr 03 17:17:36 2015 +0300 @@ -43,6 +43,8 @@ import java.beans.PropertyChangeSupport; import java.beans.PropertyChangeListener; import java.lang.ref.SoftReference; + +import sun.misc.InnocuousThread; import sun.util.logging.PlatformLogger; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; @@ -589,7 +591,12 @@ } public Thread run() { - Thread t = new Thread(appContext.getThreadGroup(), runnable); + Thread t; + if (System.getSecurityManager() == null) { + t = new Thread(appContext.getThreadGroup(), runnable); + } else { + t = new InnocuousThread(appContext.getThreadGroup(), runnable, "AppContext Disposer"); + } t.setContextClassLoader(appContext.getContextClassLoader()); t.setPriority(Thread.NORM_PRIORITY + 1); t.setDaemon(true);
--- a/src/java.desktop/share/classes/sun/awt/im/InputMethodManager.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/share/classes/sun/awt/im/InputMethodManager.java Fri Apr 03 17:17:36 2015 +0300 @@ -55,6 +55,8 @@ import java.util.prefs.Preferences; import sun.awt.InputMethodSupport; import sun.awt.SunToolkit; +import sun.misc.InnocuousThread; +import sun.misc.ManagedLocalsThread; /** * <code>InputMethodManager</code> is an abstract class that manages the input @@ -165,7 +167,12 @@ // to choose from. Otherwise, just keep the instance. if (imm.hasMultipleInputMethods()) { imm.initialize(); - Thread immThread = new Thread(imm, threadName); + Thread immThread; + if (System.getSecurityManager() == null) { + immThread = new Thread(imm, threadName); + } else { + immThread = new ManagedLocalsThread(imm, threadName); + } immThread.setDaemon(true); immThread.setPriority(Thread.NORM_PRIORITY + 1); immThread.start();
--- a/src/java.desktop/share/classes/sun/awt/image/ImageFetcher.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/share/classes/sun/awt/image/ImageFetcher.java Fri Apr 03 17:17:36 2015 +0300 @@ -27,6 +27,7 @@ import java.util.Vector; import sun.awt.AppContext; +import sun.misc.ManagedLocalsThread; /** * An ImageFetcher is a thread used to fetch ImageFetchable objects. @@ -41,7 +42,7 @@ * @author Jim Graham * @author Fred Ecks */ -class ImageFetcher extends Thread { +class ImageFetcher extends ManagedLocalsThread { static final int HIGH_PRIORITY = 8; static final int LOW_PRIORITY = 3; static final int ANIM_PRIORITY = 2; @@ -54,7 +55,7 @@ * Constructor for ImageFetcher -- only called by add() below. */ private ImageFetcher(ThreadGroup threadGroup, int index) { - super(threadGroup, "Image Fetcher " + index); + super(threadGroup, null, "Image Fetcher " + index); setDaemon(true); }
--- a/src/java.desktop/share/classes/sun/font/CreatedFontTracker.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/share/classes/sun/font/CreatedFontTracker.java Fri Apr 03 17:17:36 2015 +0300 @@ -36,6 +36,7 @@ import sun.awt.AppContext; import sun.awt.util.ThreadGroupUtils; +import sun.misc.InnocuousThread; public class CreatedFontTracker { @@ -115,18 +116,25 @@ static void init() { if (t == null) { // Add a shutdown hook to remove the temp file. - AccessController.doPrivileged( - (PrivilegedAction<Void>) () -> { - /* 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, TempFileDeletionHook::runHooks); - t.setContextClassLoader(null); - Runtime.getRuntime().addShutdownHook(t); - return null; - }); + AccessController.doPrivileged((PrivilegedAction<Void>) () -> { + if (System.getSecurityManager() == 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(); + t = new Thread(rootTG, TempFileDeletionHook::runHooks); + } else { + /* InnocuousThread is a member of a correct TG by default */ + t = new InnocuousThread(TempFileDeletionHook::runHooks); + } + /* Set context class loader to null in order to avoid + * keeping a strong reference to an application classloader. + */ + t.setContextClassLoader(null); + Runtime.getRuntime().addShutdownHook(t); + return null; + }); } }
--- a/src/java.desktop/share/classes/sun/font/SunFontManager.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/share/classes/sun/font/SunFontManager.java Fri Apr 03 17:17:36 2015 +0300 @@ -54,6 +54,7 @@ import sun.awt.SunToolkit; import sun.awt.util.ThreadGroupUtils; import sun.java2d.FontSupport; +import sun.misc.InnocuousThread; import sun.util.logging.PlatformLogger; /** @@ -2529,18 +2530,17 @@ }); } }; - AccessController.doPrivileged( - (PrivilegedAction<Void>) () -> { - /* 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; - }); + AccessController.doPrivileged((PrivilegedAction<Void>) () -> { + if (System.getSecurityManager() == null) { + ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup(); + fileCloser = new Thread(rootTG, fileCloserRunnable); + } else { + fileCloser = new InnocuousThread(fileCloserRunnable); + } + fileCloser.setContextClassLoader(null); + Runtime.getRuntime().addShutdownHook(fileCloser); + return null; + }); } } }
--- a/src/java.desktop/share/classes/sun/java2d/Disposer.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/share/classes/sun/java2d/Disposer.java Fri Apr 03 17:17:36 2015 +0300 @@ -26,6 +26,7 @@ package sun.java2d; import sun.awt.util.ThreadGroupUtils; +import sun.misc.InnocuousThread; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; @@ -81,21 +82,21 @@ } } disposerInstance = new Disposer(); - AccessController.doPrivileged( - (PrivilegedAction<Void>) () -> { - /* 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(); - Thread t = new Thread(rootTG, disposerInstance, "Java2D Disposer"); - t.setContextClassLoader(null); - t.setDaemon(true); - t.setPriority(Thread.MAX_PRIORITY); - t.start(); - return null; - } - ); + AccessController.doPrivileged((PrivilegedAction<Void>) () -> { + String name = "Java2D Disposer"; + Thread t; + if (System.getSecurityManager() == null) { + ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup(); + t = new Thread(rootTG, disposerInstance, name); + } else { + t = new InnocuousThread(disposerInstance, name); + } + t.setContextClassLoader(null); + t.setDaemon(true); + t.setPriority(Thread.MAX_PRIORITY); + t.start(); + return null; + }); } /**
--- a/src/java.desktop/share/classes/sun/java2d/loops/GraphicsPrimitive.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/share/classes/sun/java2d/loops/GraphicsPrimitive.java Fri Apr 03 17:17:36 2015 +0300 @@ -33,6 +33,7 @@ import java.awt.AlphaComposite; import java.awt.Rectangle; import sun.awt.image.BufImgSurfaceData; +import sun.awt.util.ThreadGroupUtils; import sun.java2d.SurfaceData; import sun.java2d.pipe.Region; import java.lang.reflect.Field; @@ -46,6 +47,8 @@ import java.io.FileNotFoundException; import java.security.AccessController; import java.security.PrivilegedAction; + +import sun.misc.InnocuousThread; import sun.security.action.GetPropertyAction; /** @@ -413,15 +416,19 @@ return traceout; } - public static class TraceReporter extends Thread { + public static class TraceReporter implements Runnable { public static void setShutdownHook() { - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - TraceReporter t = new TraceReporter(); - t.setContextClassLoader(null); - Runtime.getRuntime().addShutdownHook(t); - return null; + AccessController.doPrivileged((PrivilegedAction<Void>) () -> { + TraceReporter t = new TraceReporter(); + Thread thread; + if (System.getSecurityManager() == null) { + thread = new Thread(ThreadGroupUtils.getRootThreadGroup(), t); + } else { + thread = new InnocuousThread(t); } + thread.setContextClassLoader(null); + Runtime.getRuntime().addShutdownHook(thread); + return null; }); }
--- a/src/java.desktop/share/classes/sun/java2d/opengl/OGLRenderQueue.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/share/classes/sun/java2d/opengl/OGLRenderQueue.java Fri Apr 03 17:17:36 2015 +0300 @@ -28,6 +28,8 @@ import sun.awt.util.ThreadGroupUtils; import sun.java2d.pipe.RenderBuffer; import sun.java2d.pipe.RenderQueue; +import sun.misc.InnocuousThread; + import static sun.java2d.pipe.BufferedOpCodes.*; import java.security.AccessController; import java.security.PrivilegedAction; @@ -48,9 +50,7 @@ * The thread must be a member of a thread group * which will not get GCed before VM exit. */ - flusher = AccessController.doPrivileged((PrivilegedAction<QueueFlusher>) () -> { - return new QueueFlusher(ThreadGroupUtils.getRootThreadGroup()); - }); + flusher = AccessController.doPrivileged((PrivilegedAction<QueueFlusher>) QueueFlusher::new); } /** @@ -115,7 +115,7 @@ * Returns true if the current thread is the OGL QueueFlusher thread. */ public static boolean isQueueFlusherThread() { - return (Thread.currentThread() == getInstance().flusher); + return (Thread.currentThread() == getInstance().flusher.thread); } public void flushNow() { @@ -153,16 +153,22 @@ refSet.clear(); } - private class QueueFlusher extends Thread { + private class QueueFlusher implements Runnable { private boolean needsFlush; private Runnable task; private Error error; + private final Thread thread; - public QueueFlusher(ThreadGroup threadGroup) { - super(threadGroup, "Java2D Queue Flusher"); - setDaemon(true); - setPriority(Thread.MAX_PRIORITY); - start(); + public QueueFlusher() { + String name = "Java2D Queue Flusher"; + if (System.getSecurityManager() == null) { + this.thread = new Thread(ThreadGroupUtils.getRootThreadGroup(), this, name); + } else { + this.thread = new InnocuousThread(this, name); + } + thread.setDaemon(true); + thread.setPriority(Thread.MAX_PRIORITY); + thread.start(); } public synchronized void flushNow() {
--- a/src/java.desktop/share/classes/sun/print/PrintJob2D.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/share/classes/sun/print/PrintJob2D.java Fri Apr 03 17:17:36 2015 +0300 @@ -71,6 +71,7 @@ import javax.print.attribute.standard.MediaSizeName; import javax.print.attribute.standard.PageRanges; +import sun.misc.ManagedLocalsThread; import sun.print.SunPageSelection; import sun.print.SunMinMaxPage; @@ -986,8 +987,12 @@ } private void startPrinterJobThread() { - - printerJobThread = new Thread(this, "printerJobThread"); + String name = "printerJobThread"; + if (System.getSecurityManager() == null) { + printerJobThread = new Thread(this, name); + } else { + printerJobThread = new ManagedLocalsThread(this, name); + } printerJobThread.start(); }
--- a/src/java.desktop/share/classes/sun/print/ServiceNotifier.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/share/classes/sun/print/ServiceNotifier.java Fri Apr 03 17:17:36 2015 +0300 @@ -25,6 +25,8 @@ package sun.print; +import sun.misc.ManagedLocalsThread; + import java.util.Vector; import javax.print.PrintService; @@ -40,7 +42,7 @@ * to obtain the state of the attributes and notifies the listeners of * any changes. */ -class ServiceNotifier extends Thread { +class ServiceNotifier extends ManagedLocalsThread { private PrintService service; private Vector<PrintServiceAttributeListener> listeners; @@ -48,7 +50,7 @@ private PrintServiceAttributeSet lastSet; ServiceNotifier(PrintService service) { - super(service.getName() + " notifier"); + super((Runnable) null, service.getName() + " notifier"); this.service = service; listeners = new Vector<>(); try {
--- a/src/java.desktop/unix/classes/sun/awt/X11/GtkFileDialogPeer.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/unix/classes/sun/awt/X11/GtkFileDialogPeer.java Fri Apr 03 17:17:36 2015 +0300 @@ -29,6 +29,7 @@ import java.io.File; import java.io.FilenameFilter; import sun.awt.AWTAccessor; +import sun.misc.ManagedLocalsThread; /** * FileDialogPeer for the GtkFileChooser. @@ -111,13 +112,16 @@ XToolkit.awtLock(); try { if (b) { - Thread t = new Thread() { - public void run() { - showNativeDialog(); - fd.setVisible(false); - } + Runnable task = () -> { + showNativeDialog(); + fd.setVisible(false); }; - t.start(); + if (System.getSecurityManager() == null) { + new Thread(task).start(); + } else { + new ManagedLocalsThread(task).start(); + } + } else { quit(); fd.setVisible(false);
--- a/src/java.desktop/unix/classes/sun/awt/X11/InfoWindow.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/unix/classes/sun/awt/X11/InfoWindow.java Fri Apr 03 17:17:36 2015 +0300 @@ -29,6 +29,9 @@ import java.awt.event.*; import java.awt.peer.TrayIconPeer; import sun.awt.*; +import sun.misc.InnocuousThread; +import sun.misc.ManagedLocalsThread; + import java.awt.image.*; import java.text.BreakIterator; import java.util.concurrent.ArrayBlockingQueue; @@ -338,7 +341,7 @@ lineLabels[i].setBackground(Color.white); } - displayer.start(); + displayer.thread.start(); } public void display(String caption, String text, String messageType) { @@ -415,7 +418,7 @@ } public void dispose() { - displayer.interrupt(); + displayer.thread.interrupt(); super.dispose(); } @@ -444,16 +447,23 @@ } } - private class Displayer extends Thread { + private class Displayer implements Runnable { final int MAX_CONCURRENT_MSGS = 10; ArrayBlockingQueue<Message> messageQueue = new ArrayBlockingQueue<Message>(MAX_CONCURRENT_MSGS); boolean isDisplayed; + final Thread thread; Displayer() { - setDaemon(true); + if (System.getSecurityManager() == null) { + this.thread = new Thread(this); + } else { + this.thread = new ManagedLocalsThread(this); + } + this.thread.setDaemon(true); } + @Override public void run() { while (true) { Message msg = null;
--- a/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java Fri Apr 03 17:17:36 2015 +0300 @@ -266,21 +266,26 @@ awtUnlock(); } PrivilegedAction<Void> a = () -> { - Thread shutdownThread = new Thread(ThreadGroupUtils.getRootThreadGroup(), "XToolkt-Shutdown-Thread") { - public void run() { - XSystemTrayPeer peer = XSystemTrayPeer.getPeerInstance(); - if (peer != null) { - peer.dispose(); - } - if (xs != null) { - ((XAWTXSettings)xs).dispose(); - } - freeXKB(); - if (log.isLoggable(PlatformLogger.Level.FINE)) { - dumpPeers(); - } - } - }; + Runnable r = () -> { + XSystemTrayPeer peer = XSystemTrayPeer.getPeerInstance(); + if (peer != null) { + peer.dispose(); + } + if (xs != null) { + ((XAWTXSettings)xs).dispose(); + } + freeXKB(); + if (log.isLoggable(PlatformLogger.Level.FINE)) { + dumpPeers(); + } + }; + String name = "XToolkt-Shutdown-Thread"; + Thread shutdownThread; + if (System.getSecurityManager() == null) { + shutdownThread = new Thread(ThreadGroupUtils.getRootThreadGroup(), r, name); + } else { + shutdownThread = new InnocuousThread(r, name); + } shutdownThread.setContextClassLoader(null); Runtime.getRuntime().addShutdownHook(shutdownThread); return null; @@ -326,7 +331,13 @@ XWM.init(); toolkitThread = AccessController.doPrivileged((PrivilegedAction<Thread>) () -> { - Thread thread = new Thread(ThreadGroupUtils.getRootThreadGroup(), XToolkit.this, "AWT-XAWT"); + String name = "AWT-XAWT"; + Thread thread; + if (System.getSecurityManager() == null) { + thread = new Thread(ThreadGroupUtils.getRootThreadGroup(), XToolkit.this, name); + } else { + thread = new InnocuousThread(XToolkit.this, name); + } thread.setContextClassLoader(null); thread.setPriority(Thread.NORM_PRIORITY + 1); thread.setDaemon(true);
--- a/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java Fri Apr 03 17:17:36 2015 +0300 @@ -43,6 +43,7 @@ import sun.java2d.loops.SurfaceType; import sun.awt.util.ThreadGroupUtils; +import sun.misc.InnocuousThread; /** * This is an implementation of a GraphicsDevice object for a single @@ -428,7 +429,6 @@ // hook will have no effect) shutdownHookRegistered = true; PrivilegedAction<Void> a = () -> { - ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup(); Runnable r = () -> { Window old = getFullScreenWindow(); if (old != null) { @@ -436,7 +436,13 @@ setDisplayMode(origDisplayMode); } }; - Thread t = new Thread(rootTG, r,"Display-Change-Shutdown-Thread-"+screen); + String name = "Display-Change-Shutdown-Thread-" + screen; + Thread t; + if (System.getSecurityManager() == null) { + t = new Thread(ThreadGroupUtils.getRootThreadGroup(), r, name); + } else { + t = new InnocuousThread(r, name); + } t.setContextClassLoader(null); Runtime.getRuntime().addShutdownHook(t); return null;
--- a/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java Fri Apr 03 17:17:36 2015 +0300 @@ -25,6 +25,8 @@ package sun.print; +import sun.misc.ManagedLocalsThread; + import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStream; @@ -211,7 +213,12 @@ public PrintServiceLookupProvider() { // start the printer listener thread if (pollServices) { - PrinterChangeListener thr = new PrinterChangeListener(); + Thread thr; + if (System.getSecurityManager() == null) { + thr = new Thread(new PrinterChangeListener()); + } else { + thr = new ManagedLocalsThread(new PrinterChangeListener()); + } thr.setDaemon(true); thr.start(); IPPPrintService.debug_println(debugPrefix+"polling turned on"); @@ -934,8 +941,9 @@ } } - private class PrinterChangeListener extends Thread { + private class PrinterChangeListener implements Runnable { + @Override public void run() { int refreshSecs; while (true) { @@ -954,7 +962,7 @@ refreshSecs = minRefreshTime; } try { - sleep(refreshSecs * 1000); + Thread.sleep(refreshSecs * 1000); } catch (InterruptedException e) { break; }
--- a/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java Fri Apr 03 17:17:36 2015 +0300 @@ -41,6 +41,7 @@ import static sun.awt.shell.Win32ShellFolder2.*; import sun.awt.OSInfo; import sun.awt.util.ThreadGroupUtils; +import sun.misc.InnocuousThread; // NOTE: This class supersedes Win32ShellFolderManager, which was removed // from distribution after version 1.4.2. @@ -516,26 +517,22 @@ private static Thread comThread; private ComInvoker() { - super(1, 1, 0, TimeUnit.DAYS, new LinkedBlockingQueue<Runnable>()); + super(1, 1, 0, TimeUnit.DAYS, new LinkedBlockingQueue<>()); allowCoreThreadTimeOut(false); setThreadFactory(this); - final Runnable shutdownHook = new Runnable() { - public void run() { - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - shutdownNow(); - return null; - } - }); + final Runnable shutdownHook = () -> AccessController.doPrivileged((PrivilegedAction<Void>) () -> { + shutdownNow(); + return null; + }); + AccessController.doPrivileged((PrivilegedAction<Void>) () -> { + Thread t; + if (System.getSecurityManager() == null) { + t = new Thread(ThreadGroupUtils.getRootThreadGroup(), shutdownHook); + } else { + t = new InnocuousThread(shutdownHook); } - }; - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - Runtime.getRuntime().addShutdownHook( - new Thread(shutdownHook) - ); - return null; - } + Runtime.getRuntime().addShutdownHook(t); + return null; }); } @@ -550,17 +547,22 @@ } } }; - comThread = AccessController.doPrivileged((PrivilegedAction<Thread>) () -> { - /* 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(); - Thread thread = new Thread(rootTG, comRun, "Swing-Shell"); - thread.setDaemon(true); - return thread; - } - ); + comThread = AccessController.doPrivileged((PrivilegedAction<Thread>) () -> { + String name = "Swing-Shell"; + Thread thread; + if (System.getSecurityManager() == 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. + */ + thread = new Thread(ThreadGroupUtils.getRootThreadGroup(), comRun, name); + } else { + /* InnocuousThread is a member of a correct TG by default */ + thread = new InnocuousThread(comRun, name); + } + thread.setDaemon(true); + return thread; + }); return comThread; }
--- a/src/java.desktop/windows/classes/sun/awt/windows/WFileDialogPeer.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/windows/classes/sun/awt/windows/WFileDialogPeer.java Fri Apr 03 17:17:36 2015 +0300 @@ -36,6 +36,7 @@ import java.util.Vector; import sun.awt.CausedFocusEvent; import sun.awt.AWTAccessor; +import sun.misc.ManagedLocalsThread; final class WFileDialogPeer extends WWindowPeer implements FileDialogPeer { @@ -97,12 +98,11 @@ @Override public void show() { - new Thread(new Runnable() { - @Override - public void run() { - _show(); - } - }).start(); + if (System.getSecurityManager() == null) { + new Thread(this::_show).start(); + } else { + new ManagedLocalsThread(this::_show).start(); + } } @Override
--- a/src/java.desktop/windows/classes/sun/awt/windows/WPageDialogPeer.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/windows/classes/sun/awt/windows/WPageDialogPeer.java Fri Apr 03 17:17:36 2015 +0300 @@ -25,6 +25,8 @@ package sun.awt.windows; +import sun.misc.ManagedLocalsThread; + final class WPageDialogPeer extends WPrintDialogPeer { WPageDialogPeer(WPageDialog target) { @@ -39,20 +41,22 @@ @Override public void show() { - new Thread(new Runnable() { - @Override - public void run() { - // Call pageSetup even with no printer installed, this - // will display Windows error dialog and return false. - try { - ((WPrintDialog)target).setRetVal(_show()); - } catch (Exception e) { - // No exception should be thrown by native dialog code, - // but if it is we need to trap it so the thread does - // not hide is called and the thread doesn't hang. - } - ((WPrintDialog)target).setVisible(false); - } - }).start(); + Runnable runnable = () -> { + // Call pageSetup even with no printer installed, this + // will display Windows error dialog and return false. + try { + ((WPrintDialog)target).setRetVal(_show()); + } catch (Exception e) { + // No exception should be thrown by native dialog code, + // but if it is we need to trap it so the thread does + // not hide is called and the thread doesn't hang. + } + ((WPrintDialog)target).setVisible(false); + }; + if (System.getSecurityManager() == null) { + new Thread(runnable).start(); + } else { + new ManagedLocalsThread(runnable).start(); + } } }
--- a/src/java.desktop/windows/classes/sun/awt/windows/WPrintDialogPeer.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/windows/classes/sun/awt/windows/WPrintDialogPeer.java Fri Apr 03 17:17:36 2015 +0300 @@ -32,6 +32,7 @@ import java.util.Vector; import sun.awt.CausedFocusEvent; import sun.awt.AWTAccessor; +import sun.misc.ManagedLocalsThread; class WPrintDialogPeer extends WWindowPeer implements DialogPeer { @@ -67,19 +68,21 @@ @Override public void show() { - new Thread(new Runnable() { - @Override - public void run() { - try { - ((WPrintDialog)target).setRetVal(_show()); - } catch (Exception e) { - // No exception should be thrown by native dialog code, - // but if it is we need to trap it so the thread does - // not hide is called and the thread doesn't hang. - } - ((WPrintDialog)target).setVisible(false); + Runnable runnable = () -> { + try { + ((WPrintDialog)target).setRetVal(_show()); + } catch (Exception e) { + // No exception should be thrown by native dialog code, + // but if it is we need to trap it so the thread does + // not hide is called and the thread doesn't hang. } - }).start(); + ((WPrintDialog)target).setVisible(false); + }; + if (System.getSecurityManager() == null) { + new Thread(runnable).start(); + } else { + new ManagedLocalsThread(runnable).start(); + } } synchronized void setHWnd(long hwnd) {
--- a/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java Fri Apr 03 17:17:36 2015 +0300 @@ -49,6 +49,7 @@ import sun.java2d.d3d.D3DRenderQueue; import sun.java2d.opengl.OGLRenderQueue; +import sun.misc.InnocuousThread; import sun.print.PrintJob2D; import java.awt.dnd.DragSource; @@ -247,11 +248,17 @@ */ AWTAutoShutdown.notifyToolkitThreadBusy(); - // Find a root TG and attach Appkit thread to it + // Find a root TG and attach toolkit thread to it ThreadGroup rootTG = AccessController.doPrivileged( (PrivilegedAction<ThreadGroup>) ThreadGroupUtils::getRootThreadGroup); if (!startToolkitThread(this, rootTG)) { - Thread toolkitThread = new Thread(rootTG, this, "AWT-Windows"); + String name = "AWT-Windows"; + Thread toolkitThread; + if (System.getSecurityManager() == null) { + toolkitThread = new Thread(rootTG, this, name); + } else { + toolkitThread = new InnocuousThread(this, name); + } toolkitThread.setDaemon(true); toolkitThread.start(); } @@ -278,7 +285,12 @@ private void registerShutdownHook() { AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - Thread shutdown = new Thread(ThreadGroupUtils.getRootThreadGroup(), this::shutdown); + Thread shutdown; + if (System.getSecurityManager() == null) { + shutdown = new Thread(ThreadGroupUtils.getRootThreadGroup(), this::shutdown); + } else { + shutdown = new InnocuousThread(this::shutdown); + } shutdown.setContextClassLoader(null); Runtime.getRuntime().addShutdownHook(shutdown); return null;
--- a/src/java.desktop/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java Fri Apr 03 17:17:36 2015 +0300 @@ -48,6 +48,7 @@ import sun.java2d.windows.GDIWindowSurfaceData; import sun.java2d.d3d.D3DSurfaceData.D3DWindowSurfaceData; import sun.java2d.windows.WindowsFlags; +import sun.misc.InnocuousThread; /** * This class handles rendering to the screen with the D3D pipeline. @@ -92,22 +93,25 @@ public D3DScreenUpdateManager() { done = false; - AccessController.doPrivileged( - (PrivilegedAction<Void>) () -> { - ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup(); - Thread shutdown = new Thread(rootTG, () -> { - done = true; - wakeUpUpdateThread(); - }); - shutdown.setContextClassLoader(null); - try { - Runtime.getRuntime().addShutdownHook(shutdown); - } catch (Exception e) { - done = true; - } - return null; - } - ); + AccessController.doPrivileged((PrivilegedAction<Void>) () -> { + Runnable shutdownRunnable = () -> { + done = true; + wakeUpUpdateThread(); + }; + Thread shutdown; + if (System.getSecurityManager() == null) { + shutdown = new Thread(ThreadGroupUtils.getRootThreadGroup(), shutdownRunnable); + } else { + shutdown = new InnocuousThread(shutdownRunnable); + } + shutdown.setContextClassLoader(null); + try { + Runtime.getRuntime().addShutdownHook(shutdown); + } catch (Exception e) { + done = true; + } + return null; + }); } /** @@ -345,17 +349,21 @@ */ private synchronized void startUpdateThread() { if (screenUpdater == null) { - screenUpdater = AccessController.doPrivileged( - (PrivilegedAction<Thread>) () -> { - 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); - return t; - }); + screenUpdater = AccessController.doPrivileged((PrivilegedAction<Thread>) () -> { + Thread t; + String name = "D3D Screen Updater"; + if (System.getSecurityManager() == null) { + t = new Thread(ThreadGroupUtils.getRootThreadGroup(), + D3DScreenUpdateManager.this, + name); + } else { + t = new InnocuousThread(D3DScreenUpdateManager.this, name); + } + // REMIND: should it be higher? + t.setPriority(Thread.NORM_PRIORITY + 2); + t.setDaemon(true); + return t; + }); screenUpdater.start(); } else { wakeUpUpdateThread();
--- a/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java Fri Aug 01 13:31:03 2014 +0200 +++ b/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java Fri Apr 03 17:17:36 2015 +0300 @@ -25,6 +25,8 @@ package sun.print; +import sun.misc.ManagedLocalsThread; + import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; @@ -97,7 +99,12 @@ return; } // start the printer listener thread - PrinterChangeListener thr = new PrinterChangeListener(); + Thread thr; + if (System.getSecurityManager() == null) { + thr = new Thread(new PrinterChangeListener()); + } else { + thr = new ManagedLocalsThread(new PrinterChangeListener()); + } thr.setDaemon(true); thr.start(); } /* else condition ought to never happen! */ @@ -316,12 +323,13 @@ return defaultPrintService; } - class PrinterChangeListener extends Thread { + class PrinterChangeListener implements Runnable { long chgObj; PrinterChangeListener() { chgObj = notifyFirstPrinterChange(null); } + @Override public void run() { if (chgObj != -1) { while (true) {