All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
co.paralleluniverse.concurrent.util.ThreadAccess Maven / Gradle / Ivy
Go to download
The core library for Fibers on Java, compatible with Java 11-16. Forked from puniverse/quasar
/*
* Quasar: lightweight threads and actors for the JVM.
* Copyright (c) 2013-2014, Parallel Universe Software Co. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation
*
* or (per the licensee's choosing)
*
* under the terms of the GNU Lesser General Public License version 3.0
* as published by the Free Software Foundation.
*/
package co.paralleluniverse.concurrent.util;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import static co.paralleluniverse.common.reflection.ReflectionUtil.accessible;
import java.lang.ref.*;
import java.lang.reflect.*;
import java.security.*;
import java.util.*;
/**
*
* @author pron
*/
public class ThreadAccess {
private static final VarHandle TARGET;
private static final VarHandle THREAD_LOCALS;
private static final VarHandle INHERITABLE_THREAD_LOCALS;
private static final VarHandle CONTEXT_CLASS_LOADER;
private static final VarHandle INHERITED_ACCESS_CONTROL_CONTEXT;
private static final Constructor threadLocalMapConstructor;
private static final Constructor threadLocalMapInheritedConstructor;
// private static final Method threadLocalMapSet;
private static final Field threadLocalMapTableField;
private static final Field threadLocalMapSizeField;
private static final Field threadLocalMapThresholdField;
private static final Class threadLocalMapEntryClass;
private static final Constructor threadLocalMapEntryConstructor;
private static final Field threadLocalMapEntryValueField;
static {
try {
MethodHandles.Lookup l = MethodHandles.lookup();
l = MethodHandles.privateLookupIn(Thread.class, l);
TARGET = l.findVarHandle(Thread.class, "target", Runnable.class); // l.unreflectVarHandle(Thread.class.getDeclaredField("target"));
THREAD_LOCALS = l.unreflectVarHandle(Thread.class.getDeclaredField("threadLocals"));
INHERITABLE_THREAD_LOCALS = l.unreflectVarHandle(Thread.class.getDeclaredField("inheritableThreadLocals"));
CONTEXT_CLASS_LOADER = l.unreflectVarHandle(Thread.class.getDeclaredField("contextClassLoader"));
VarHandle _inheritedAccessControlContext = null;
try {
_inheritedAccessControlContext = l.unreflectVarHandle(Thread.class.getDeclaredField("inheritedAccessControlContext"));
} catch (NoSuchFieldException e) {
}
INHERITED_ACCESS_CONTROL_CONTEXT = _inheritedAccessControlContext;
Class threadLocalMapClass = Class.forName("java.lang.ThreadLocal$ThreadLocalMap");
threadLocalMapConstructor = accessible(threadLocalMapClass.getDeclaredConstructor(ThreadLocal.class, Object.class));
threadLocalMapInheritedConstructor = accessible(threadLocalMapClass.getDeclaredConstructor(threadLocalMapClass));
// threadLocalMapSet = accessible(threadLocalMapClass.getDeclaredMethod("set", ThreadLocal.class, Object.class));
threadLocalMapTableField = accessible(threadLocalMapClass.getDeclaredField("table"));
threadLocalMapSizeField = accessible(threadLocalMapClass.getDeclaredField("size"));
threadLocalMapThresholdField = accessible(threadLocalMapClass.getDeclaredField("threshold"));
threadLocalMapEntryClass = Class.forName("java.lang.ThreadLocal$ThreadLocalMap$Entry");
threadLocalMapEntryConstructor = accessible(threadLocalMapEntryClass.getDeclaredConstructor(ThreadLocal.class, Object.class));
threadLocalMapEntryValueField = accessible(threadLocalMapEntryClass.getDeclaredField("value"));
} catch (Exception ex) {
throw new AssertionError(ex);
}
}
public static Runnable getTarget(Thread thread) {
return (Runnable) TARGET.get(thread);
}
public static void setTarget(Thread thread, Runnable target) {
TARGET.set(thread, target);
}
public static Object getThreadLocals(Thread thread) {
return (Object) THREAD_LOCALS.get(thread);
}
public static void setThreadLocals(Thread thread, Object threadLocals) {
THREAD_LOCALS.set(thread, threadLocals);
}
public static Object getInheritableThreadLocals(Thread thread) {
return (Object) INHERITABLE_THREAD_LOCALS.get(thread);
}
public static void setInheritableThreadLocals(Thread thread, Object inheritableThreadLocals) {
INHERITABLE_THREAD_LOCALS.set(thread, inheritableThreadLocals);
}
private static Object createThreadLocalMap(ThreadLocal tl, Object firstValue) {
try {
return threadLocalMapConstructor.newInstance(tl, firstValue);
} catch (ReflectiveOperationException ex) {
throw new AssertionError(ex);
}
}
public static Object createInheritedMap(Object inheritableThreadLocals) {
try {
return threadLocalMapInheritedConstructor.newInstance(inheritableThreadLocals);
} catch (ReflectiveOperationException ex) {
throw new AssertionError(ex);
}
}
// public static void set(Thread t, ThreadLocal tl, Object value) {
// Object map = getThreadLocals(t);
// if (map != null)
// set(map, tl, value);
// else
// setThreadLocals(t, createThreadLocalMap(tl, value));
// }
//
// private static void set(Object map, ThreadLocal tl, Object value) {
// try {
// threadLocalMapSet.invoke(map, tl, value);
// } catch (ReflectiveOperationException e) {
// throw new AssertionError(e);
// }
// }
// createInheritedMap works only for InheritableThreadLocals
public static Object cloneThreadLocalMap(Object orig) {
try {
Object clone = createThreadLocalMap(new ThreadLocal(), null);
Object origTable = threadLocalMapTableField.get(orig);
final int len = Array.getLength(origTable);
Object tableClone = Array.newInstance(threadLocalMapEntryClass, len);
for (int i = 0; i < len; i++) {
Object entry = Array.get(origTable, i);
if (entry != null)
Array.set(tableClone, i, cloneThreadLocalMapEntry(entry));
}
threadLocalMapTableField.set(clone, tableClone);
threadLocalMapSizeField.setInt(clone, threadLocalMapSizeField.getInt(orig));
threadLocalMapThresholdField.setInt(clone, threadLocalMapThresholdField.getInt(orig));
return clone;
} catch (ReflectiveOperationException ex) {
throw new AssertionError(ex);
}
}
private static Object cloneThreadLocalMapEntry(Object entry) {
try {
final ThreadLocal key = ((Reference) entry).get();
final Object value = threadLocalMapEntryValueField.get(entry);
return threadLocalMapEntryConstructor.newInstance(key, value);
} catch (Exception ex) {
throw new AssertionError(ex);
}
}
public static Map toMap(Object threadLocalMap) {
try {
final Map map = new HashMap<>();
Object table = threadLocalMapTableField.get(threadLocalMap);
final int len = Array.getLength(table);
for (int i = 0; i < len; i++) {
Object entry = Array.get(table, i);
if (entry != null)
map.put(((Reference) entry).get(), threadLocalMapEntryValueField.get(entry));
}
return map;
} catch (Exception ex) {
throw new AssertionError(ex);
}
}
public static ClassLoader getContextClassLoader(Thread thread) {
return (ClassLoader) CONTEXT_CLASS_LOADER.get(thread);
}
public static void setContextClassLoader(Thread thread, ClassLoader classLoader) {
CONTEXT_CLASS_LOADER.set(thread, classLoader);
}
public static AccessControlContext getInheritedAccessControlContext(Thread thread) {
if (INHERITED_ACCESS_CONTROL_CONTEXT == null)
return null;
return (AccessControlContext) INHERITED_ACCESS_CONTROL_CONTEXT.get(thread);
}
public static void setInheritedAccessControlContext(Thread thread, AccessControlContext accessControlContext) {
if (INHERITED_ACCESS_CONTROL_CONTEXT != null)
INHERITED_ACCESS_CONTROL_CONTEXT.set(thread, accessControlContext);
}
}