changeset 12325:e95a13de2d36 jdk8u141-b01

8172204: Better Thread Pool execution Reviewed-by: alanb, skoivu, rriggs
author igerasim
date Mon, 13 Mar 2017 18:24:21 -0700
parents c729ab3b13ae
children 70b0eb614c92
files src/share/classes/java/util/concurrent/ThreadPoolExecutor.java
diffstat 1 files changed, 20 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java	Wed Mar 15 20:09:04 2017 -0700
+++ b/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java	Mon Mar 13 18:24:21 2017 -0700
@@ -34,6 +34,10 @@
  */
 
 package java.util.concurrent;
+
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.concurrent.locks.AbstractQueuedSynchronizer;
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.ReentrantLock;
@@ -569,6 +573,9 @@
     private static final RuntimePermission shutdownPerm =
         new RuntimePermission("modifyThread");
 
+    /* The context to be used when executing the finalizer, or null. */
+    private final AccessControlContext acc;
+
     /**
      * Class Worker mainly maintains interrupt control state for
      * threads running tasks, along with other minor bookkeeping.
@@ -1307,6 +1314,9 @@
             throw new IllegalArgumentException();
         if (workQueue == null || threadFactory == null || handler == null)
             throw new NullPointerException();
+        this.acc = System.getSecurityManager() == null ?
+                null :
+                AccessController.getContext();
         this.corePoolSize = corePoolSize;
         this.maximumPoolSize = maximumPoolSize;
         this.workQueue = workQueue;
@@ -1472,9 +1482,18 @@
     /**
      * Invokes {@code shutdown} when this executor is no longer
      * referenced and it has no threads.
+     *
+     * <p>This method is invoked with privileges that are restricted by
+     * the security context of the caller that invokes the constructor.
      */
     protected void finalize() {
-        shutdown();
+        SecurityManager sm = System.getSecurityManager();
+        if (sm == null || acc == null) {
+            shutdown();
+        } else {
+            PrivilegedAction<Void> pa = () -> { shutdown(); return null; };
+            AccessController.doPrivileged(pa, acc);
+        }
     }
 
     /**