1 /*
   2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   3  *
   4  * This code is free software; you can redistribute it and/or modify it
   5  * under the terms of the GNU General Public License version 2 only, as
   6  * published by the Free Software Foundation.
   7  *
   8  * This code is distributed in the hope that it will be useful, but WITHOUT
   9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  11  * version 2 for more details (a copy is included in the LICENSE file that
  12  * accompanied this code).
  13  *
  14  * You should have received a copy of the GNU General Public License version
  15  * 2 along with this work; if not, write to the Free Software Foundation,
  16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  17  *
  18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  19  * or visit www.oracle.com if you need additional information or have any
  20  * questions.
  21  */
  22 
  23 /*
  24  * This file is available under and governed by the GNU General Public
  25  * License version 2 only, as published by the Free Software Foundation.
  26  * However, the following notice accompanied the original version of this
  27  * file:
  28  *
  29  * Written by Doug Lea and Martin Buchholz with assistance from
  30  * members of JCP JSR-166 Expert Group and released to the public
  31  * domain, as explained at
  32  * http://creativecommons.org/publicdomain/zero/1.0/
  33  */
  34 
  35 import java.lang.invoke.MethodHandles;
  36 import java.lang.invoke.VarHandle;
  37 import java.util.concurrent.CountDownLatch;
  38 import java.util.concurrent.ForkJoinPool;
  39 import java.util.concurrent.ForkJoinTask;
  40 import java.util.concurrent.Future;
  41 import java.util.stream.Stream;
  42 
  43 import junit.framework.Test;
  44 import junit.framework.TestSuite;
  45 
  46 public class ForkJoinPool9Test extends JSR166TestCase {
  47     public static void main(String[] args) {
  48         main(suite(), args);
  49     }
  50 
  51     public static Test suite() {
  52         return new TestSuite(ForkJoinPool9Test.class);
  53     }
  54 
  55     /**
  56      * Check handling of common pool thread context class loader
  57      */
  58     public void testCommonPoolThreadContextClassLoader() throws Throwable {
  59         if (!testImplementationDetails) return;
  60 
  61         // Ensure common pool has at least one real thread
  62         String prop = System.getProperty(
  63             "java.util.concurrent.ForkJoinPool.common.parallelism");
  64         if ("0".equals(prop)) return;
  65 
  66         VarHandle CCL =
  67             MethodHandles.privateLookupIn(Thread.class, MethodHandles.lookup())
  68             .findVarHandle(Thread.class, "contextClassLoader", ClassLoader.class);
  69         ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
  70         boolean haveSecurityManager = (System.getSecurityManager() != null);
  71         CountDownLatch runInCommonPoolStarted = new CountDownLatch(1);
  72         ClassLoader classLoaderDistinctFromSystemClassLoader
  73             = ClassLoader.getPlatformClassLoader();
  74         assertNotSame(classLoaderDistinctFromSystemClassLoader,
  75                       systemClassLoader);
  76         Runnable runInCommonPool = () -> {
  77             runInCommonPoolStarted.countDown();
  78             assertTrue(ForkJoinTask.inForkJoinPool());
  79             assertSame(ForkJoinPool.commonPool(), ForkJoinTask.getPool());
  80             Thread currentThread = Thread.currentThread();
  81 
  82             Stream.of(systemClassLoader, null).forEach(cl -> {
  83                 if (randomBoolean())
  84                     // should always be permitted, without effect
  85                     currentThread.setContextClassLoader(cl);
  86                 });
  87 
  88             Stream.of(currentThread.getContextClassLoader(),
  89                       (ClassLoader) CCL.get(currentThread))
  90             .forEach(cl -> assertTrue(cl == systemClassLoader || cl == null));
  91 
  92             if (haveSecurityManager)
  93                 assertThrows(
  94                     SecurityException.class,
  95                     () -> System.getProperty("foo"),
  96                     () -> currentThread.setContextClassLoader(
  97                         classLoaderDistinctFromSystemClassLoader));
  98             // TODO ?
  99 //          if (haveSecurityManager
 100 //              && Thread.currentThread().getClass().getSimpleName()
 101 //                 .equals("InnocuousForkJoinWorkerThread"))
 102 //              assertThrows(SecurityException.class, /* ?? */);
 103         };
 104         Future<?> f = ForkJoinPool.commonPool().submit(runInCommonPool);
 105         // Ensure runInCommonPool is truly running in the common pool,
 106         // by giving this thread no opportunity to "help" on get().
 107         await(runInCommonPoolStarted);
 108         assertNull(f.get());
 109     }
 110 
 111 }