001: package sisc.interpreter;
002:
003: import java.lang.ref.*;
004: import java.util.*;
005:
006: import sisc.data.SchemeThread;
007: import sisc.util.Util;
008: import sisc.env.DynamicEnvironment;
009:
010: public class ThreadContext extends Util {
011:
012: public static class State {
013: public final Interpreter interpreter;
014: public final ClassLoader classLoader;
015:
016: public State(Interpreter r, ClassLoader cl) {
017: this .interpreter = r;
018: this .classLoader = cl;
019: }
020: }
021:
022: protected Stack states = new Stack();
023: protected Random r = new Random();
024:
025: public WeakReference hostThread;
026: public boolean interrupt = false;
027: public long unicityMajor = genUnicityMajor();
028: public char unicityMinor = 0;
029:
030: public ThreadContext() {
031: }
032:
033: /*********** Unique Value Support ********************/
034: protected long genUnicityMajor() {
035: return System.currentTimeMillis()
036: + ((r.nextInt() & 0xffff) * 311040000000L);
037: }
038:
039: public long nextUnique() {
040: if (++unicityMinor == 0)
041: unicityMajor = genUnicityMajor();
042: return unicityMajor + (unicityMinor * 31104000000L);
043: }
044:
045: /*********** state stack maintenance ***********/
046:
047: public Interpreter currentInterpreter() {
048: return (states.empty() ? null
049: : ((State) states.peek()).interpreter);
050: }
051:
052: public Interpreter currentInterpreter(AppContext ctx) {
053: for (Iterator it = states.iterator(); it.hasNext();) {
054: Interpreter r = ((State) it.next()).interpreter;
055: if (r.dynenv.ctx == ctx)
056: return r;
057: }
058: return null;
059: }
060:
061: protected void pushState(State s) {
062: states.push(s);
063: }
064:
065: protected State popState() {
066: return (State) states.pop();
067: }
068:
069: public Thread nativeThread() {
070: if (hostThread == null)
071: return null;
072: SchemeThread st = (SchemeThread) hostThread.get();
073: if (st == null)
074: return null;
075: else
076: return st.thread;
077: }
078:
079: public void setHostThread(DynamicEnvironment dynenv, Thread thread) {
080: if (nativeThread() != thread) {
081: //Wrap the thread in a SchemeThread with no thunk.
082: SchemeThread st = new SchemeThread(dynenv, null);
083: st.thread = thread;
084: hostThread = new WeakReference(st);
085: }
086: }
087:
088: }
089: /*
090: * The contents of this file are subject to the Mozilla Public
091: * License Version 1.1 (the "License"); you may not use this file
092: * except in compliance with the License. You may obtain a copy of
093: * the License at http://www.mozilla.org/MPL/
094: *
095: * Software distributed under the License is distributed on an "AS
096: * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
097: * implied. See the License for the specific language governing
098: * rights and limitations under the License.
099: *
100: * The Original Code is the Second Interpreter of Scheme Code (SISC).
101: *
102: * The Initial Developer of the Original Code is Scott G. Miller.
103: * Portions created by Scott G. Miller are Copyright (C) 2000-2007
104: * Scott G. Miller. All Rights Reserved.
105: *
106: * Contributor(s):
107: * Matthias Radestock
108: *
109: * Alternatively, the contents of this file may be used under the
110: * terms of the GNU General Public License Version 2 or later (the
111: * "GPL"), in which case the provisions of the GPL are applicable
112: * instead of those above. If you wish to allow use of your
113: * version of this file only under the terms of the GPL and not to
114: * allow others to use your version of this file under the MPL,
115: * indicate your decision by deleting the provisions above and
116: * replace them with the notice and other provisions required by
117: * the GPL. If you do not delete the provisions above, a recipient
118: * may use your version of this file under either the MPL or the
119: * GPL.
120: */
|