20 |
|
import java.util.concurrent.RunnableFuture; |
21 |
|
import java.util.concurrent.ThreadLocalRandom; |
22 |
|
import java.util.concurrent.TimeUnit; |
23 |
+ |
import java.security.AccessControlContext; |
24 |
+ |
import java.security.ProtectionDomain; |
25 |
+ |
import java.security.Permissions; |
26 |
|
|
27 |
|
/** |
28 |
|
* An {@link ExecutorService} for running {@link ForkJoinTask}s. |
114 |
|
* <li>{@code java.util.concurrent.ForkJoinPool.common.exceptionHandler} |
115 |
|
* - the class name of a {@link UncaughtExceptionHandler} |
116 |
|
* </ul> |
117 |
+ |
* If a {@link SecurityManager} is present and no factory is |
118 |
+ |
* specified, then the default pool uses a factory supplying |
119 |
+ |
* threads that have no {@link Permissions} enabled. |
120 |
|
* The system class loader is used to load these classes. |
121 |
|
* Upon any error in establishing these settings, default parameters |
122 |
|
* are used. It is possible to disable or limit the use of threads in |
478 |
|
* task status checks) in inapplicable cases amounts to an odd |
479 |
|
* form of limited spin-wait before blocking in ForkJoinTask.join. |
480 |
|
* |
481 |
+ |
* As a more appropriate default in managed environments, unless |
482 |
+ |
* overridden by system properties, we use workers of subclass |
483 |
+ |
* InnocuousForkJoinWorkerThread when there is a SecurityManager |
484 |
+ |
* present. These workers have no permissions set, do not belong |
485 |
+ |
* to any user-defined ThreadGroup, and erase all ThreadLocals |
486 |
+ |
* after executing any top-level task (see WorkQueue.runTask). The |
487 |
+ |
* associated mechanics (mainly in ForkJoinWorkerThread) may be |
488 |
+ |
* JVM-dependent and must access particular Thread class fields to |
489 |
+ |
* achieve this effect. |
490 |
+ |
* |
491 |
|
* Style notes |
492 |
|
* =========== |
493 |
|
* |
869 |
|
*/ |
870 |
|
final void runTask(ForkJoinTask<?> task) { |
871 |
|
if ((currentSteal = task) != null) { |
872 |
+ |
ForkJoinWorkerThread thread; |
873 |
|
task.doExec(); |
874 |
|
ForkJoinTask<?>[] a = array; |
875 |
|
int md = mode; |
887 |
|
t.doExec(); |
888 |
|
} |
889 |
|
} |
890 |
+ |
if ((thread = owner) != null) // no need to do in finally clause |
891 |
+ |
thread.afterTopLevelExec(); |
892 |
|
} |
893 |
|
} |
894 |
|
|
2074 |
|
((c & ~AC_MASK) | |
2075 |
|
((c & AC_MASK) + AC_UNIT)))); |
2076 |
|
} |
2077 |
< |
if ((b = q.base) - q.top < 0 && (t = q.pollAt(b)) != null) { |
2078 |
< |
(w.currentSteal = t).doExec(); |
2060 |
< |
w.currentSteal = ps; |
2061 |
< |
} |
2077 |
> |
if ((b = q.base) - q.top < 0 && (t = q.pollAt(b)) != null) |
2078 |
> |
w.runTask(t); |
2079 |
|
} |
2080 |
|
else if (active) { // decrement active count without queuing |
2081 |
|
long nc = ((c = ctl) & ~AC_MASK) | ((c & AC_MASK) - AC_UNIT); |
3269 |
|
*/ |
3270 |
|
private static ForkJoinPool makeCommonPool() { |
3271 |
|
int parallelism = -1; |
3272 |
< |
ForkJoinWorkerThreadFactory factory |
3256 |
< |
= defaultForkJoinWorkerThreadFactory; |
3272 |
> |
ForkJoinWorkerThreadFactory factory = null; |
3273 |
|
UncaughtExceptionHandler handler = null; |
3274 |
|
try { // ignore exceptions in accessing/parsing properties |
3275 |
|
String pp = System.getProperty |
3288 |
|
getSystemClassLoader().loadClass(hp).newInstance()); |
3289 |
|
} catch (Exception ignore) { |
3290 |
|
} |
3291 |
< |
|
3291 |
> |
if (factory == null) { |
3292 |
> |
if (System.getSecurityManager() == null) |
3293 |
> |
factory = defaultForkJoinWorkerThreadFactory; |
3294 |
> |
else // use security-managed default |
3295 |
> |
factory = new InnocuousForkJoinWorkerThreadFactory(); |
3296 |
> |
} |
3297 |
|
if (parallelism < 0 && // default 1 less than #cores |
3298 |
|
(parallelism = Runtime.getRuntime().availableProcessors() - 1) <= 0) |
3299 |
|
parallelism = 1; |
3303 |
|
"ForkJoinPool.commonPool-worker-"); |
3304 |
|
} |
3305 |
|
|
3306 |
+ |
/** |
3307 |
+ |
* Factory for innocuous worker threads |
3308 |
+ |
*/ |
3309 |
+ |
static final class InnocuousForkJoinWorkerThreadFactory |
3310 |
+ |
implements ForkJoinWorkerThreadFactory { |
3311 |
+ |
|
3312 |
+ |
/** |
3313 |
+ |
* An ACC to restrict permissions for the factory itself. |
3314 |
+ |
* The constructed workers have no permissions set. |
3315 |
+ |
*/ |
3316 |
+ |
private static final AccessControlContext innocuousAcc; |
3317 |
+ |
static { |
3318 |
+ |
Permissions innocuousPerms = new Permissions(); |
3319 |
+ |
innocuousPerms.add(modifyThreadPermission); |
3320 |
+ |
innocuousPerms.add(new RuntimePermission( |
3321 |
+ |
"enableContextClassLoaderOverride")); |
3322 |
+ |
innocuousPerms.add(new RuntimePermission( |
3323 |
+ |
"modifyThreadGroup")); |
3324 |
+ |
innocuousAcc = new AccessControlContext(new ProtectionDomain[] { |
3325 |
+ |
new ProtectionDomain(null, innocuousPerms) |
3326 |
+ |
}); |
3327 |
+ |
} |
3328 |
+ |
|
3329 |
+ |
public final ForkJoinWorkerThread newThread(ForkJoinPool pool) { |
3330 |
+ |
return (ForkJoinWorkerThread.InnocuousForkJoinWorkerThread) |
3331 |
+ |
java.security.AccessController.doPrivileged( |
3332 |
+ |
new java.security.PrivilegedAction<ForkJoinWorkerThread>() { |
3333 |
+ |
public ForkJoinWorkerThread run() { |
3334 |
+ |
return new ForkJoinWorkerThread. |
3335 |
+ |
InnocuousForkJoinWorkerThread(pool); |
3336 |
+ |
}}, innocuousAcc); |
3337 |
+ |
} |
3338 |
+ |
} |
3339 |
+ |
|
3340 |
|
} |