1a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson/* 229957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 329957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * 429957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * This code is free software; you can redistribute it and/or modify it 529957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * under the terms of the GNU General Public License version 2 only, as 629957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * published by the Free Software Foundation. Oracle designates this 729957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * particular file as subject to the "Classpath" exception as provided 829957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * by Oracle in the LICENSE file that accompanied this code. 929957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * 1029957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * This code is distributed in the hope that it will be useful, but WITHOUT 1129957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1229957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1329957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * version 2 for more details (a copy is included in the LICENSE file that 1429957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * accompanied this code). 1529957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * 1629957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * You should have received a copy of the GNU General Public License version 1729957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * 2 along with this work; if not, write to the Free Software Foundation, 1829957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1929957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * 2029957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2129957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * or visit www.oracle.com if you need additional information or have any 2229957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * questions. 2329957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer */ 2429957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer 2529957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer/* 2629957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * This file is available under and governed by the GNU General Public 2729957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * License version 2 only, as published by the Free Software Foundation. 2829957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * However, the following notice accompanied the original version of this 2929957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * file: 3029957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * 31a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * Written by Doug Lea with assistance from members of JCP JSR-166 32a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * Expert Group and released to the public domain, as explained at 33a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * http://creativecommons.org/publicdomain/zero/1.0/ 34a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 35a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 36a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilsonpackage java.util.concurrent; 37a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 38b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport java.security.AccessControlContext; 39b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport java.security.ProtectionDomain; 40b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak 41a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson/** 42a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * A thread managed by a {@link ForkJoinPool}, which executes 43a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * {@link ForkJoinTask}s. 44a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * This class is subclassable solely for the sake of adding 45a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * functionality -- there are no overridable methods dealing with 46a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * scheduling or execution. However, you can override initialization 47a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * and termination methods surrounding the main task processing loop. 48a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * If you do create such a subclass, you will also need to supply a 4975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * custom {@link ForkJoinPool.ForkJoinWorkerThreadFactory} to 5075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@linkplain ForkJoinPool#ForkJoinPool use it} in a {@code ForkJoinPool}. 51a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * 52a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * @since 1.7 53a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * @author Doug Lea 54a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 55a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilsonpublic class ForkJoinWorkerThread extends Thread { 56a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /* 57a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * ForkJoinWorkerThreads are managed by ForkJoinPools and perform 5891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * ForkJoinTasks. For explanation, see the internal documentation 5991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * of class ForkJoinPool. 60a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * 6191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * This class just maintains links to its pool and WorkQueue. The 6291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * pool field is set immediately upon construction, but the 6391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * workQueue field is not set until a call to registerWorker 6491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * completes. This leads to a visibility race, that is tolerated 6591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * by requiring that the workQueue field is only accessed by the 6691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * owning thread. 67b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * 68b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * Support for (non-public) subclass InnocuousForkJoinWorkerThread 69b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * requires that we break quite a lot of encapsulation (via Unsafe) 70b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * both here and in the subclass to access and set Thread fields. 71a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 72a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 7391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle final ForkJoinPool pool; // the pool this thread works in 7491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle final ForkJoinPool.WorkQueue workQueue; // work-stealing mechanics 75a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 76a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 77a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * Creates a ForkJoinWorkerThread operating in the given pool. 78a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * 79a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * @param pool the pool this thread works in 80a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * @throws NullPointerException if pool is null 81a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 82a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson protected ForkJoinWorkerThread(ForkJoinPool pool) { 8391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // Use a placeholder until a useful name can be set in registerWorker 8491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle super("aForkJoinWorkerThread"); 85a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson this.pool = pool; 8691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle this.workQueue = pool.registerWorker(this); 87a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 88a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 89a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 90b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * Version for InnocuousForkJoinWorkerThread. 91b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak */ 92b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak ForkJoinWorkerThread(ForkJoinPool pool, ThreadGroup threadGroup, 93b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak AccessControlContext acc) { 94b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak super(threadGroup, null, "aForkJoinWorkerThread"); 95b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak U.putOrderedObject(this, INHERITEDACCESSCONTROLCONTEXT, acc); 96b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak eraseThreadLocals(); // clear before registering 97b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak this.pool = pool; 98b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak this.workQueue = pool.registerWorker(this); 99b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak } 100b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak 101b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak /** 102a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * Returns the pool hosting this thread. 103a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * 104a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * @return the pool 105a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 106a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson public ForkJoinPool getPool() { 107a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson return pool; 108a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 109a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 110a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 11175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns the unique index number of this thread in its pool. 11275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The returned value ranges from zero to the maximum number of 11375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * threads (minus one) that may exist in the pool, and does not 11475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * change during the lifetime of the thread. This method may be 11575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * useful for applications that track status or collect results 11675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * per-worker-thread rather than per-task. 117a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * 118a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * @return the index number 119a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 120a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson public int getPoolIndex() { 121b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak return workQueue.getPoolIndex(); 122a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 123a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 124a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 125a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * Initializes internal state after construction but before 126a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * processing any tasks. If you override this method, you must 127a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * invoke {@code super.onStart()} at the beginning of the method. 128a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * Initialization requires care: Most fields must have legal 129a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * default values, to ensure that attempted accesses from other 130a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * threads work correctly even before this thread starts 131a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * processing tasks. 132a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 133a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson protected void onStart() { 134a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 135a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 136a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 137a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * Performs cleanup associated with termination of this worker 138a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * thread. If you override this method, you must invoke 139a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * {@code super.onTermination} at the end of the overridden method. 140a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * 141a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * @param exception the exception causing this thread to abort due 142a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * to an unrecoverable error, or {@code null} if completed normally 143a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 144a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson protected void onTermination(Throwable exception) { 145a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 146a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 147a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 148a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * This method is required to be public, but should never be 149a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * called explicitly. It performs the main run loop to execute 150a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * {@link ForkJoinTask}s. 151a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 152a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson public void run() { 153b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak if (workQueue.array == null) { // only run once 154b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak Throwable exception = null; 15591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle try { 156b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak onStart(); 157b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak pool.runWorker(workQueue); 15891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle } catch (Throwable ex) { 159b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak exception = ex; 16091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle } finally { 161b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak try { 162b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak onTermination(exception); 163b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak } catch (Throwable ex) { 164b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak if (exception == null) 165b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak exception = ex; 166b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak } finally { 167b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak pool.deregisterWorker(this, exception); 168b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak } 169b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak } 170b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak } 171b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak } 172b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak 173b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak /** 174b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * Erases ThreadLocals by nulling out Thread maps. 175b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak */ 176b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak final void eraseThreadLocals() { 177b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak U.putObject(this, THREADLOCALS, null); 178b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak U.putObject(this, INHERITABLETHREADLOCALS, null); 179b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak } 180b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak 181b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak /** 182b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * Non-public hook method for InnocuousForkJoinWorkerThread. 183b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak */ 184b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak void afterTopLevelExec() { 185b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak } 186b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak 187b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak // Set up to allow setting thread fields in constructor 188b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe(); 189b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak private static final long THREADLOCALS; 190b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak private static final long INHERITABLETHREADLOCALS; 191b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak private static final long INHERITEDACCESSCONTROLCONTEXT; 192b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak static { 193b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak try { 194b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak THREADLOCALS = U.objectFieldOffset 195b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak (Thread.class.getDeclaredField("threadLocals")); 196b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak INHERITABLETHREADLOCALS = U.objectFieldOffset 197b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak (Thread.class.getDeclaredField("inheritableThreadLocals")); 198b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak INHERITEDACCESSCONTROLCONTEXT = U.objectFieldOffset 199b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak (Thread.class.getDeclaredField("inheritedAccessControlContext")); 200b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak } catch (ReflectiveOperationException e) { 201b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak throw new Error(e); 202b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak } 203b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak } 204b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak 205b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak /** 206b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * A worker thread that has no permissions, is not a member of any 207b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * user-defined ThreadGroup, and erases all ThreadLocals after 208b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * running each top-level task. 209b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak */ 210b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak static final class InnocuousForkJoinWorkerThread extends ForkJoinWorkerThread { 211b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak /** The ThreadGroup for all InnocuousForkJoinWorkerThreads */ 212b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak private static final ThreadGroup innocuousThreadGroup = 213b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak createThreadGroup(); 214b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak 215b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak /** An AccessControlContext supporting no privileges */ 216b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak private static final AccessControlContext INNOCUOUS_ACC = 217b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak new AccessControlContext( 218b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak new ProtectionDomain[] { 219b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak new ProtectionDomain(null, null) 220b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak }); 221b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak 222b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak InnocuousForkJoinWorkerThread(ForkJoinPool pool) { 223b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak super(pool, innocuousThreadGroup, INNOCUOUS_ACC); 224b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak } 225b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak 226b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak @Override // to erase ThreadLocals 227b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak void afterTopLevelExec() { 228b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak eraseThreadLocals(); 229b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak } 230b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak 231b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak @Override // to always report system loader 232b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak public ClassLoader getContextClassLoader() { 233b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak return ClassLoader.getSystemClassLoader(); 234b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak } 235b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak 236b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak @Override // to silently fail 237b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak public void setUncaughtExceptionHandler(UncaughtExceptionHandler x) { } 238b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak 239b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak @Override // paranoically 240b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak public void setContextClassLoader(ClassLoader cl) { 241b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak throw new SecurityException("setContextClassLoader"); 242b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak } 243b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak 244b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak /** 245b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * Returns a new group with the system ThreadGroup (the 246b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * topmost, parent-less group) as parent. Uses Unsafe to 247b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * traverse Thread.group and ThreadGroup.parent fields. 248b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak */ 249b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak private static ThreadGroup createThreadGroup() { 250b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak try { 251b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak sun.misc.Unsafe u = sun.misc.Unsafe.getUnsafe(); 252b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak long tg = u.objectFieldOffset 253b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak (Thread.class.getDeclaredField("group")); 254b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak long gp = u.objectFieldOffset 255b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak (ThreadGroup.class.getDeclaredField("parent")); 256b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak ThreadGroup group = (ThreadGroup) 257b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak u.getObject(Thread.currentThread(), tg); 258b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak while (group != null) { 259b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak ThreadGroup parent = (ThreadGroup)u.getObject(group, gp); 260b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak if (parent == null) 261b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak return new ThreadGroup(group, 262b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak "InnocuousForkJoinWorkerThreadGroup"); 263b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak group = parent; 264b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak } 265b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak } catch (ReflectiveOperationException e) { 266b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak throw new Error(e); 267a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 268b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak // fall through if null as cannot-happen safeguard 269b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak throw new Error("Cannot create ThreadGroup"); 270a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 271a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 272b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak 273a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson} 274