8048983: Enhance thread contexts in JAXP
Reviewed-by: chegar, lancea, dfuchs, hawtin
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/SafeThread.java Thu Apr 02 10:35:54 2015 -0700
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.org.apache.xml.internal.utils;
+
+import sun.misc.Unsafe;
+
+/**
+ * This is a combination of ThreadControllerWrapper's inner class SafeThread
+ * that was introduced as a fix for CR 6607339
+ * and sun.misc.ManagedLocalsThread, a thread that has it's thread locals, and
+ * inheritable thread locals erased on construction. Except the run method,
+ * it is identical to sun.misc.ManagedLocalsThread.
+ */
+public class SafeThread extends Thread {
+
+ private static final Unsafe UNSAFE;
+ private static final long THREAD_LOCALS;
+ private static final long INHERITABLE_THREAD_LOCALS;
+
+ private volatile boolean ran = false;
+
+ public SafeThread(Runnable target) {
+ super(target);
+ eraseThreadLocals();
+ }
+
+ public SafeThread(Runnable target, String name) {
+ super(target, name);
+ eraseThreadLocals();
+ }
+
+ public SafeThread(ThreadGroup group, Runnable target, String name) {
+ super(group, target, name);
+ eraseThreadLocals();
+ }
+
+ public final void run() {
+ if (Thread.currentThread() != this) {
+ throw new IllegalStateException("The run() method in a"
+ + " SafeThread cannot be called from another thread.");
+ }
+ synchronized (this) {
+ if (!ran) {
+ ran = true;
+ } else {
+ throw new IllegalStateException("The run() method in a"
+ + " SafeThread cannot be called more than once.");
+ }
+ }
+ super.run();
+ }
+
+ /**
+ * Drops all thread locals (and inherited thread locals).
+ */
+ public final void eraseThreadLocals() {
+ UNSAFE.putObject(this, THREAD_LOCALS, null);
+ UNSAFE.putObject(this, INHERITABLE_THREAD_LOCALS, null);
+ }
+
+ static {
+ UNSAFE = Unsafe.getUnsafe();
+ Class<?> t = Thread.class;
+ try {
+ THREAD_LOCALS = UNSAFE.objectFieldOffset(t.getDeclaredField("threadLocals"));
+ INHERITABLE_THREAD_LOCALS = UNSAFE.objectFieldOffset(t.getDeclaredField("inheritableThreadLocals"));
+ } catch (Exception e) {
+ throw new Error(e);
+ }
+ }
+
+}
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/ThreadControllerWrapper.java Thu Mar 05 12:05:56 2015 +0300
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/ThreadControllerWrapper.java Thu Apr 02 10:35:54 2015 -0700
@@ -3,11 +3,12 @@
* DO NOT REMOVE OR ALTER!
*/
/*
- * Copyright 1999-2004 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
@@ -17,110 +18,73 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/*
- * $Id: ThreadControllerWrapper.java,v 1.2.4.1 2005/09/15 08:15:59 suresh_emailid Exp $
- */
package com.sun.org.apache.xml.internal.utils;
/**
- * A utility class that wraps the ThreadController, which is used
- * by IncrementalSAXSource for the incremental building of DTM.
+ * A utility class that wraps the ThreadController, which is used by
+ * IncrementalSAXSource for the incremental building of DTM.
*/
-public class ThreadControllerWrapper
-{
-
- /** The ThreadController pool */
- private static ThreadController m_tpool = new ThreadController();
-
- public static Thread runThread(Runnable runnable, int priority)
- {
- return m_tpool.run(runnable, priority);
- }
-
- public static void waitThread(Thread worker, Runnable task)
- throws InterruptedException
- {
- m_tpool.waitThread(worker, task);
- }
-
- /**
- * Thread controller utility class for incremental SAX source. Must
- * be overriden with a derived class to support thread pooling.
- *
- * All thread-related stuff is in this class.
- */
- public static class ThreadController
- {
+public class ThreadControllerWrapper {
/**
- * This class was introduced as a fix for CR 6607339.
+ * The ThreadController pool
*/
- final class SafeThread extends Thread {
- private volatile boolean ran = false;
-
- public SafeThread(Runnable target) {
- super(target);
- }
+ private static ThreadController m_tpool = new ThreadController();
- public final void run() {
- if (Thread.currentThread() != this) {
- throw new IllegalStateException("The run() method in a"
- + " SafeThread cannot be called from another thread.");
- }
- synchronized (this) {
- if (!ran) {
- ran = true;
- }
- else {
- throw new IllegalStateException("The run() method in a"
- + " SafeThread cannot be called more than once.");
- }
- }
- super.run();
- }
+ public static Thread runThread(Runnable runnable, int priority) {
+ return m_tpool.run(runnable, priority);
+ }
+
+ public static void waitThread(Thread worker, Runnable task)
+ throws InterruptedException {
+ m_tpool.waitThread(worker, task);
}
/**
- * Will get a thread from the pool, execute the task
- * and return the thread to the pool.
- *
- * The return value is used only to wait for completion
- *
+ * Thread controller utility class for incremental SAX source. Must be
+ * overridden with a derived class to support thread pooling.
*
- * NEEDSDOC @param task
- * @param priority if >0 the task will run with the given priority
- * ( doesn't seem to be used in xalan, since it's allways the default )
- * @return The thread that is running the task, can be used
- * to wait for completion
+ * All thread-related stuff is in this class.
*/
- public Thread run(Runnable task, int priority)
- {
+ public static class ThreadController {
- Thread t = new SafeThread(task);
-
- t.start();
+ /**
+ * Will get a thread from the pool, execute the task and return the
+ * thread to the pool.
+ *
+ * The return value is used only to wait for completion
+ *
+ *
+ * @param task the Runnable
+ *
+ * @param priority if >0 the task will run with the given priority (
+ * doesn't seem to be used in xalan, since it's always the default )
+ * @return The thread that is running the task, can be used to wait for
+ * completion
+ */
+ public Thread run(Runnable task, int priority) {
- // if( priority > 0 )
- // t.setPriority( priority );
- return t;
- }
+ Thread t = new SafeThread(task);
+ t.start();
+
+ //if( priority > 0 )
+ // t.setPriority( priority );
+ return t;
+ }
- /**
- * Wait until the task is completed on the worker
- * thread.
- *
- * NEEDSDOC @param worker
- * NEEDSDOC @param task
- *
- * @throws InterruptedException
- */
- public void waitThread(Thread worker, Runnable task)
- throws InterruptedException
- {
+ /**
+ * Wait until the task is completed on the worker thread.
+ *
+ * @param worker worker thread
+ * @param task the Runnable
+ *
+ * @throws InterruptedException
+ */
+ public void waitThread(Thread worker, Runnable task)
+ throws InterruptedException {
- // This should wait until the transformThread is considered not alive.
- worker.join();
+ // This should wait until the transformThread is considered not alive.
+ worker.join();
+ }
}
- }
-
}