KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > tools > example > debug > tty > ThreadInfo


1 /*
2  * @(#)ThreadInfo.java 1.25 05/11/17
3  *
4  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 /*
8  * Copyright (c) 1997-1999 by Sun Microsystems, Inc. All Rights Reserved.
9  *
10  * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
11  * modify and redistribute this software in source and binary code form,
12  * provided that i) this copyright notice and license appear on all copies of
13  * the software; and ii) Licensee does not utilize the software in a manner
14  * which is disparaging to Sun.
15  *
16  * This software is provided "AS IS," without a warranty of any kind. ALL
17  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
18  * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
19  * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
20  * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
21  * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
22  * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
23  * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
24  * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
25  * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGES.
27  *
28  * This software is not designed or intended for use in on-line control of
29  * aircraft, air traffic, aircraft navigation or aircraft communications; or in
30  * the design, construction, operation or maintenance of any nuclear
31  * facility. Licensee represents and warrants that it will not use or
32  * redistribute the Software for such purposes.
33  */

34
35 package com.sun.tools.example.debug.tty;
36
37 import com.sun.jdi.ThreadReference;
38 import com.sun.jdi.ThreadGroupReference;
39 import com.sun.jdi.IncompatibleThreadStateException;
40 import com.sun.jdi.StackFrame;
41 import java.util.List JavaDoc;
42 import java.util.ArrayList JavaDoc;
43 import java.util.Collections JavaDoc;
44 import java.util.Iterator JavaDoc;
45 import java.io.*;
46
47 class ThreadInfo {
48     // This is a list of all known ThreadInfo objects. It survives
49
// ThreadInfo.invalidateAll, unlike the other static fields below.
50
private static List JavaDoc threads = Collections.synchronizedList(new ArrayList JavaDoc());
51     private static boolean gotInitialThreads = false;
52
53     private static ThreadInfo current = null;
54     private static ThreadGroupReference group = null;
55
56     private final ThreadReference thread;
57     private int currentFrameIndex = 0;
58
59     private ThreadInfo(ThreadReference thread) {
60         this.thread = thread;
61         if (thread == null) {
62             MessageOutput.fatalError("Internal error: null ThreadInfo created");
63         }
64     }
65
66     private static void initThreads() {
67         if (!gotInitialThreads) {
68             Iterator JavaDoc iter = Env.vm().allThreads().iterator();
69             while (iter.hasNext()) {
70                 ThreadReference thread = (ThreadReference)iter.next();
71                 threads.add(new ThreadInfo(thread));
72             }
73             gotInitialThreads = true;
74         }
75     }
76
77     static void addThread(ThreadReference thread) {
78         synchronized (threads) {
79             initThreads();
80             ThreadInfo ti = new ThreadInfo(thread);
81             // Guard against duplicates. Duplicates can happen during
82
// initialization when a particular thread might be added both
83
// by a thread start event and by the initial call to threads()
84
if (getThreadInfo(thread) == null) {
85                 threads.add(ti);
86             }
87         }
88     }
89
90     static void removeThread(ThreadReference thread) {
91         if (thread.equals(ThreadInfo.current)) {
92             // Current thread has died.
93

94             // Be careful getting the thread name. If its death happens
95
// as part of VM termination, it may be too late to get the
96
// information, and an exception will be thrown.
97
String JavaDoc currentThreadName;
98             try {
99                currentThreadName = "\"" + thread.name() + "\"";
100             } catch (Exception JavaDoc e) {
101                currentThreadName = "";
102             }
103                  
104             setCurrentThread(null);
105
106             MessageOutput.println();
107             MessageOutput.println("Current thread died. Execution continuing...",
108                                   currentThreadName);
109         }
110         threads.remove(getThreadInfo(thread));
111     }
112
113     static List JavaDoc threads() {
114         synchronized(threads) {
115             initThreads();
116             // Make a copy to allow iteration without synchronization
117
return new ArrayList JavaDoc(threads);
118         }
119     }
120
121     static void invalidateAll() {
122         current = null;
123         group = null;
124         synchronized (threads) {
125             Iterator JavaDoc iter = threads().iterator();
126             while (iter.hasNext()) {
127                 ThreadInfo ti = (ThreadInfo)iter.next();
128                 ti.invalidate();
129             }
130         }
131     }
132
133     static void setThreadGroup(ThreadGroupReference tg) {
134         group = tg;
135     }
136     
137     static void setCurrentThread(ThreadReference tr) {
138         if (tr == null) {
139             setCurrentThreadInfo(null);
140         } else {
141             ThreadInfo tinfo = getThreadInfo(tr);
142             setCurrentThreadInfo(tinfo);
143         }
144     }
145
146     static void setCurrentThreadInfo(ThreadInfo tinfo) {
147         current = tinfo;
148         if (current != null) {
149             current.invalidate();
150         }
151     }
152
153     /**
154      * Get the current ThreadInfo object.
155      *
156      * @return the ThreadInfo for the current thread.
157      */

158     static ThreadInfo getCurrentThreadInfo() {
159         return current;
160     }
161     
162     /**
163      * Get the thread from this ThreadInfo object.
164      *
165      * @return the Thread wrapped by this ThreadInfo.
166      */

167     ThreadReference getThread() {
168         return thread;
169     }
170
171     static ThreadGroupReference group() {
172     if (group == null) {
173             // Current thread group defaults to the first top level
174
// thread group.
175
setThreadGroup((ThreadGroupReference)
176                            Env.vm().topLevelThreadGroups().get(0));
177     }
178         return group;
179     }
180     
181     static ThreadInfo getThreadInfo(long id) {
182         ThreadInfo retInfo = null;
183
184         synchronized (threads) {
185             Iterator JavaDoc iter = threads().iterator();
186             while (iter.hasNext()) {
187                 ThreadInfo ti = (ThreadInfo)iter.next();
188                 if (ti.thread.uniqueID() == id) {
189                    retInfo = ti;
190                    break;
191                 }
192             }
193         }
194         return retInfo;
195     }
196
197     static ThreadInfo getThreadInfo(ThreadReference tr) {
198         return getThreadInfo(tr.uniqueID());
199     }
200
201     static ThreadInfo getThreadInfo(String JavaDoc idToken) {
202         ThreadInfo tinfo = null;
203         if (idToken.startsWith("t@")) {
204             idToken = idToken.substring(2);
205         }
206         try {
207             long threadId = Long.decode(idToken).longValue();
208             tinfo = getThreadInfo(threadId);
209         } catch (NumberFormatException JavaDoc e) {
210             tinfo = null;
211         }
212         return tinfo;
213     }
214
215     /**
216      * Get the thread stack frames.
217      *
218      * @return a <code>List</code> of the stack frames.
219      */

220     List JavaDoc getStack() throws IncompatibleThreadStateException {
221         return thread.frames();
222     }
223
224     /**
225      * Get the current stackframe.
226      *
227      * @return the current stackframe.
228      */

229     StackFrame getCurrentFrame() throws IncompatibleThreadStateException {
230         if (thread.frameCount() == 0) {
231             return null;
232         }
233         return thread.frame(currentFrameIndex);
234     }
235
236     /**
237      * Invalidate the current stackframe index.
238      */

239     void invalidate() {
240         currentFrameIndex = 0;
241     }
242
243     /* Throw IncompatibleThreadStateException if not suspended */
244     private void assureSuspended() throws IncompatibleThreadStateException {
245         if (!thread.isSuspended()) {
246             throw new IncompatibleThreadStateException();
247         }
248     }
249
250     /**
251      * Get the current stackframe index.
252      *
253      * @return the number of the current stackframe. Frame zero is the
254      * closest to the current program counter
255      */

256     int getCurrentFrameIndex() {
257         return currentFrameIndex;
258     }
259
260     /**
261      * Set the current stackframe to a specific frame.
262      *
263      * @param nFrame the number of the desired stackframe. Frame zero is the
264      * closest to the current program counter
265      * @exception IllegalAccessError when the thread isn't
266      * suspended or waiting at a breakpoint
267      * @exception ArrayIndexOutOfBoundsException when the
268      * requested frame is beyond the stack boundary
269      */

270     void setCurrentFrameIndex(int nFrame) throws IncompatibleThreadStateException {
271         assureSuspended();
272         if ((nFrame < 0) || (nFrame >= thread.frameCount())) {
273             throw new ArrayIndexOutOfBoundsException JavaDoc();
274         }
275         currentFrameIndex = nFrame;
276     }
277
278     /**
279      * Change the current stackframe to be one or more frames higher
280      * (as in, away from the current program counter).
281      *
282      * @param nFrames the number of stackframes
283      * @exception IllegalAccessError when the thread isn't
284      * suspended or waiting at a breakpoint
285      * @exception ArrayIndexOutOfBoundsException when the
286      * requested frame is beyond the stack boundary
287      */

288     void up(int nFrames) throws IncompatibleThreadStateException {
289         setCurrentFrameIndex(currentFrameIndex + nFrames);
290     }
291
292     /**
293      * Change the current stackframe to be one or more frames lower
294      * (as in, toward the current program counter). *
295      * @param nFrames the number of stackframes
296      * @exception IllegalAccessError when the thread isn't
297      * suspended or waiting at a breakpoint
298      * @exception ArrayIndexOutOfBoundsException when the
299      * requested frame is beyond the stack boundary
300      */

301     void down(int nFrames) throws IncompatibleThreadStateException {
302         setCurrentFrameIndex(currentFrameIndex - nFrames);
303     }
304
305 }
306                             
307
Popular Tags