001: package org.python.core;
002:
003: /**
004: *
005: * @deprecated Java 1 support is deprecated -- remove.
006: *
007: */
008: class ThreadStateMapping {
009: //Java 1 support is deprecated -- remove this check.
010: private static boolean checkedJava2 = false;
011:
012: public static ThreadStateMapping makeMapping() {
013: if (!checkedJava2) {
014: checkedJava2 = true;
015: String version = System.getProperty("java.version");
016: if (version.compareTo("1.2") >= 0) {
017: try {
018: Class c = Class
019: .forName("org.python.core.ThreadStateMapping2");
020: return (ThreadStateMapping) c.newInstance();
021: } catch (Throwable t) {
022: }
023: }
024: }
025: return new ThreadStateMapping();
026: }
027:
028: // There are hacks that could improve performance slightly in the
029: // interim, but I'd rather wait for the right solution.
030: private static java.util.Hashtable threads;
031:
032: private static ThreadState cachedThreadState;
033:
034: // Mechanism provided by Drew Morrissey and approved by JimH which
035: // occasionally cleans up dead threads, preventing the hashtable from
036: // leaking memory when many threads are used (e.g. in an embedded
037: // application).
038: //
039: // counter of additions to the threads table
040: private static int additionCounter = 0;
041:
042: // maximum number of thread additions before cleanup is triggered
043: private static final int MAX_ADDITIONS = 25;
044:
045: public ThreadState getThreadState(PySystemState newSystemState) {
046: Thread t = Thread.currentThread();
047: ThreadState ts = cachedThreadState;
048: if (ts != null && ts.thread == t) {
049: return ts;
050: }
051:
052: if (threads == null) {
053: threads = new java.util.Hashtable();
054: }
055:
056: ts = (ThreadState) threads.get(t);
057: if (ts == null) {
058: if (newSystemState == null) {
059: Py.writeDebug("threadstate", "no current system state");
060: // t.dumpStack();
061: newSystemState = Py.defaultSystemState;
062: }
063: ts = new ThreadState(t, newSystemState);
064: // System.err.println("new ts: "+ts+", "+ts.systemState);
065: threads.put(t, ts);
066: // increase the counter each time a thread reference is added
067: // to the table
068: additionCounter++;
069: if (additionCounter > MAX_ADDITIONS) {
070: cleanupThreadTable();
071: additionCounter = 0;
072: }
073: }
074: cachedThreadState = ts;
075: // System.err.println("returning ts: "+ts+", "+ts.systemState);
076: return ts;
077: }
078:
079: /**
080: * Enumerates through the thread table looking for dead thread references
081: * and removes them. Called internally by getThreadState(PySystemState).
082: */
083: private void cleanupThreadTable() {
084: // loop through thread table removing dead thread references
085: for (java.util.Enumeration e = threads.keys(); e
086: .hasMoreElements();) {
087: try {
088: Object key = e.nextElement();
089: ThreadState tempThreadState = (ThreadState) threads
090: .get(key);
091: if ((tempThreadState != null)
092: && (tempThreadState.thread != null)
093: && !tempThreadState.thread.isAlive()) {
094: threads.remove(key);
095: }
096: } catch (ClassCastException exc) {
097: // XXX: we should throw some type of exception here
098: }
099: }
100: }
101: }
|