Index: ThreadStateMapping.java =================================================================== --- ThreadStateMapping.java (revision 7066) +++ ThreadStateMapping.java (working copy) @@ -1,26 +1,69 @@ package org.python.core; +import java.util.ArrayList; +import java.lang.ref.WeakReference; + class ThreadStateMapping { - private static final ThreadLocal cachedThreadState = new ThreadLocal(); + private static final ThreadLocal cachedThreadState = + new ThreadLocal() + { + @Override + protected Object[] initialValue() + { + return new Object[1]; + } + }; + private ArrayList> threadStateList = new ArrayList>(); + private boolean isShutdown = false; + public ThreadState getThreadState(PySystemState newSystemState) { - ThreadState ts = cachedThreadState.get(); + + //initial check for usual case outside syncronized block for efficiency + ThreadState ts = (ThreadState)cachedThreadState.get()[0]; + if (ts != null) { return ts; } + synchronized(this) + { + //check again within synchronized block to guard against race condition + Object[] threadLocal = cachedThreadState.get(); + if(threadLocal[0] != null) + return (ThreadState)threadLocal[0]; - Thread t = Thread.currentThread(); - if (newSystemState == null) { - Py.writeDebug("threadstate", "no current system state"); - if (Py.defaultSystemState == null) { - PySystemState.initialize(); + Thread t = Thread.currentThread(); + if (newSystemState == null) { + Py.writeDebug("threadstate", "no current system state"); + if (Py.defaultSystemState == null) { + PySystemState.initialize(); + } + newSystemState = Py.defaultSystemState; } - newSystemState = Py.defaultSystemState; + + ts = new ThreadState(t, newSystemState); + + if(! isShutdown) + { + threadLocal[0] = ts; + threadStateList.add(new WeakReference(threadLocal)); + } + return ts; } + } - ts = new ThreadState(t, newSystemState); - cachedThreadState.set(ts); - return ts; + public synchronized void shutdown() + { + isShutdown = true; + for(WeakReference ref : threadStateList) + { + Object[] o = ref.get(); + if(o != null) + { + o[0] = null; + } + } + threadStateList.clear(); } }