1 /*
2  * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 /*
27  * This source code is provided to illustrate the usage of a given feature
28  * or technique and has been deliberately simplified. Additional steps
29  * required for a production-quality application, such as security checks,
30  * input validation and proper error handling, might not be present in
31  * this sample code.
32  */
33 
34 
35 package com.sun.tools.example.debug.bdi;
36 
37 import com.sun.jdi.*;
38 
39 //### Should handle target VM death or connection failure cleanly.
40 
41 public class ThreadInfo {
42 
43     private ThreadReference thread;
44     private int status;
45 
46     private int frameCount;
47 
48     Object userObject;  // User-supplied annotation.
49 
50     private boolean interrupted = false;
51 
assureInterrupted()52     private void assureInterrupted() throws VMNotInterruptedException {
53         if (!interrupted) {
54             throw new VMNotInterruptedException();
55         }
56     }
57 
ThreadInfo(ThreadReference thread)58     ThreadInfo (ThreadReference thread) {
59         this.thread = thread;
60         this.frameCount = -1;
61     }
62 
thread()63     public ThreadReference thread() {
64         return thread;
65     }
66 
getStatus()67     public int getStatus() throws VMNotInterruptedException {
68         assureInterrupted();
69         update();
70         return status;
71     }
72 
getFrameCount()73     public int getFrameCount() throws VMNotInterruptedException {
74         assureInterrupted();
75         update();
76         return frameCount;
77     }
78 
getFrame(int index)79     public StackFrame getFrame(int index) throws VMNotInterruptedException {
80         assureInterrupted();
81         update();
82         try {
83             return thread.frame(index);
84         } catch (IncompatibleThreadStateException e) {
85             // Should not happen
86             interrupted = false;
87             throw new VMNotInterruptedException();
88         }
89     }
90 
getUserObject()91     public Object getUserObject() {
92         return userObject;
93     }
94 
setUserObject(Object obj)95     public void setUserObject(Object obj) {
96         userObject = obj;
97     }
98 
99     // Refresh upon first access after cache is cleared.
100 
update()101     void update() throws VMNotInterruptedException {
102         if (frameCount == -1) {
103             try {
104                 status = thread.status();
105                 frameCount = thread.frameCount();
106             } catch (IncompatibleThreadStateException e) {
107                 // Should not happen
108                 interrupted = false;
109                 throw new VMNotInterruptedException();
110             }
111         }
112     }
113 
114     // Called from 'ExecutionManager'.
115 
validate()116     void validate() {
117         interrupted = true;
118     }
119 
invalidate()120     void invalidate() {
121         interrupted = false;
122         frameCount = -1;
123         status = ThreadReference.THREAD_STATUS_UNKNOWN;
124     }
125 
126 }
127