1package com.jogamp.nativewindow.awt;
3import java.lang.ref.WeakReference;
4import java.lang.reflect.Method;
5import java.security.PrivilegedAction;
7import com.jogamp.common.ExceptionUtils;
8import com.jogamp.common.util.RunnableTask;
9import com.jogamp.common.util.SecurityUtil;
10import com.jogamp.common.util.UnsafeUtil;
12import jogamp.nativewindow.jawt.JAWTUtil;
21 private static final boolean DEBUG;
23 private static final Method getAppContextMethod;
24 private static final Object mainThreadAppContextLock =
new Object();
25 private volatile WeakReference<Object> mainThreadAppContextWR =
null;
26 private volatile WeakReference<ThreadGroup> mainThreadGroupWR =
null;
29 DEBUG = JAWTUtil.DEBUG;
30 final Method[] _getAppContextMethod = {
null };
31 SecurityUtil.doPrivileged(
new PrivilegedAction<Object>() {
34 return UnsafeUtil.doWithoutIllegalAccessLogger(
new PrivilegedAction<Object>() {
38 final Class<?> appContextClass = Class.forName(
"sun.awt.AppContext");
39 _getAppContextMethod[0] = appContextClass.getMethod(
"getAppContext");
40 _getAppContextMethod[0].setAccessible(
true);
41 }
catch(
final Throwable ex) {
42 ExceptionUtils.dumpThrowable(
"AppContextInfo(Bug 1004)", ex);
46 getAppContextMethod = _getAppContextMethod[0];
80 final WeakReference<ThreadGroup> tgRef = mainThreadGroupWR;
81 return null != tgRef ? tgRef.get() :
null;
106 final RunnableTask rt;
108 rt = RunnableTask.invokeOnCurrentThread(runnable);
110 System.err.println(
"Bug 1004: Invoke.0 on current AppContext: "+rt);
114 final String tName = threadBaseName + (
null != tg ?
"-OnAppContextTG" :
"-OnSystemTG" );
115 rt = RunnableTask.invokeOnNewThread(tg, tName, waitUntilDone, runnable);
117 final int tgHash =
null != tg ? tg.hashCode() : 0;
118 System.err.println(
"Bug 1004: Invoke.1 on new AppContext: "+rt+
", tg "+tg+
" "+toHexString(tgHash));
132 public final boolean update(
final String info) {
133 if (
null != getAppContextMethod ) {
135 final Object thisThreadAppContext = fetchAppContext();
136 final boolean tgMapped =
null != thisThreadAppContext;
138 final Thread thread = Thread.currentThread();
139 final ThreadGroup threadGroup = thread.getThreadGroup();
140 final Object mainThreadAppContext;
142 final WeakReference<Object> _mainThreadAppContextWR = mainThreadAppContextWR;
143 mainThreadAppContext =
null != _mainThreadAppContextWR ? _mainThreadAppContextWR.get() :
null;
148 if(
null == mainThreadAppContext ||
149 mainThreadAppContext != thisThreadAppContext ) {
151 final int mainThreadAppContextHash =
null != mainThreadAppContext ? mainThreadAppContext.hashCode() : 0;
152 final int thisThreadAppContextHash;
153 synchronized(mainThreadAppContextLock) {
154 mainThreadGroupWR =
new WeakReference<ThreadGroup>(threadGroup);
155 mainThreadAppContextWR =
new WeakReference<Object>(thisThreadAppContext);
156 thisThreadAppContextHash = thisThreadAppContext.hashCode();
159 System.err.println(
"Bug 1004[TGMapped "+tgMapped+
"]: Init AppContext @ "+info+
" on thread "+thread.getName()+
" "+toHexString(thread.hashCode())+
160 ": tg "+threadGroup.getName()+
" "+toHexString(threadGroup.hashCode())+
161 " -> appCtx [ main "+mainThreadAppContext+
" "+toHexString(mainThreadAppContextHash)+
162 " -> this "+thisThreadAppContext+
" "+toHexString(thisThreadAppContextHash) +
" ] ");
167 final int mainThreadAppContextHash = mainThreadAppContext.hashCode();
168 final int thisThreadAppContextHash = thisThreadAppContext.hashCode();
169 System.err.println(
"Bug 1004[TGMapped "+tgMapped+
"]: OK AppContext @ "+info+
" on thread "+thread.getName()+
" "+toHexString(thread.hashCode())+
170 ": tg "+threadGroup.getName()+
" "+toHexString(threadGroup.hashCode())+
171 " : appCtx [ this "+thisThreadAppContext+
" "+toHexString(thisThreadAppContextHash)+
172 " , main "+mainThreadAppContext+
" "+toHexString(mainThreadAppContextHash) +
" ] ");
178 final int mainThreadAppContextHash =
null != mainThreadAppContext ? mainThreadAppContext.hashCode() : 0;
179 final int thisThreadAppContextHash =
null != thisThreadAppContext ? thisThreadAppContext.hashCode() : 0;
180 System.err.println(
"Bug 1004[TGMapped "+tgMapped+
"]: No AppContext @ "+info+
" on thread "+thread.getName()+
" "+toHexString(thread.hashCode())+
181 ": tg "+threadGroup.getName()+
" "+toHexString(threadGroup.hashCode())+
182 " -> appCtx [ this "+thisThreadAppContext+
" "+toHexString(thisThreadAppContextHash)+
183 " -> main "+mainThreadAppContext+
" "+toHexString(mainThreadAppContextHash) +
" ] ");
189 private static Object fetchAppContext() {
191 return getAppContextMethod.invoke(
null);
192 }
catch(
final Exception ex) {
193 ExceptionUtils.dumpThrowable(
"AppContextInfo(Bug 1004)", ex);
198 private static String toHexString(
final int i) {
199 return "0x"+Integer.toHexString(i);
Instance of this class holds information about a ThreadGroup associated sun.awt.AppContext.
final boolean isValid()
Returns true if this instance has valid sun.awt.AppContext information, i.e.
final boolean update(final String info)
Update sun.awt.AppContext information for the current ThreadGroup if uninitialized or sun....
final ThreadGroup getCachedThreadGroup()
Returns the ThreadGroup belonging to the last known sun.awt.AppContext as queried via update(String).
AppContextInfo(final String info)
RunnableTask invokeOnAppContextThread(final boolean waitUntilDone, final Runnable runnable, final String threadBaseName)
Invokes runnable on a Thread belonging to the sun.awt.AppContext ThreadGroup, see getCachedThreadGrou...