KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > debug > ui > monitors > JavaMonitor


1 /*******************************************************************************
2  * Copyright (c) 2004, 2005 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.debug.ui.monitors;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.List JavaDoc;
15
16 import org.eclipse.debug.core.DebugEvent;
17 import org.eclipse.debug.core.DebugException;
18 import org.eclipse.debug.core.DebugPlugin;
19 import org.eclipse.debug.core.ILaunch;
20 import org.eclipse.debug.core.model.IDebugTarget;
21 import org.eclipse.jdt.debug.core.IJavaObject;
22 import org.eclipse.jdt.debug.core.IJavaThread;
23
24 /**
25  * Represent a Java monitor in the threads and monitors model.
26  */

27 public class JavaMonitor {
28     
29     /**
30      * The underlying object.
31      */

32     private IJavaObject fMonitor;
33     
34     /**
35      * The thread which owns this monitor
36      */

37     private JavaMonitorThread fOwningThread;
38     /**
39      * The threads waiting for this monitor.
40      */

41     private JavaMonitorThread[] fWaitingThreads= new JavaMonitorThread[0];
42     /**
43      * Indicate if this monitor is currently part of a deadlock.
44      */

45     private boolean fIsInDeadlock;
46     /**
47      * Indicate that the information for this monitor need to be update, it
48      * may have changed.
49      */

50     private boolean fToUpdate= true;
51     
52     /**
53      * The List of JavaContendedMonitor and JavaOwnedMonitor associated with this
54      * monitor.
55      */

56     private List JavaDoc fElements= new ArrayList JavaDoc();
57     
58     public JavaMonitor(IJavaObject monitor) {
59         fMonitor= monitor;
60     }
61     
62     public IJavaObject getMonitor() {
63         return fMonitor;
64     }
65     
66     /* (non-Javadoc)
67      * @see org.eclipse.debug.core.model.IDebugElement#getDebugTarget()
68      */

69     public IDebugTarget getDebugTarget() {
70         return fMonitor.getDebugTarget();
71     }
72     /* (non-Javadoc)
73      * @see org.eclipse.debug.core.model.IDebugElement#getLaunch()
74      */

75     public ILaunch getLaunch() {
76         return fMonitor.getLaunch();
77     }
78     /* (non-Javadoc)
79      * @see org.eclipse.debug.core.model.IDebugElement#getModelIdentifier()
80      */

81     public String JavaDoc getModelIdentifier() {
82         return fMonitor.getModelIdentifier();
83     }
84     
85     /**
86      * Returns the thread which owns this monitor, refresh the data
87      * first if need.
88      */

89     protected JavaMonitorThread getOwningThread0() {
90         if (fToUpdate) {
91             update();
92         }
93         return fOwningThread;
94     }
95     
96     /**
97      * Returns the threads waiting for this monitor, refresh the data
98      * first if need.
99      */

100     protected JavaMonitorThread[] getWaitingThreads0() {
101         if (fToUpdate) {
102             update();
103         }
104         return fWaitingThreads;
105     }
106     
107     /**
108      * Update the information for this monitor.
109      * @return <code>true</code> if the owning thread or
110      * the waiting threads changed.
111      */

112     private boolean update() {
113         boolean changed= false;
114         boolean toRemove= false;
115         ThreadMonitorManager threadMonitorManager= ThreadMonitorManager.getDefault();
116         synchronized (this) {
117             if (!fToUpdate) {
118                 return false;
119             }
120             try {
121                 if (fMonitor.isAllocated()) {
122                     // update the owning thread
123
IJavaThread owningThread= fMonitor.getOwningThread();
124                     if (owningThread == null) {
125                         changed= fOwningThread != null;
126                         fOwningThread= null;
127                     } else {
128                         changed= fOwningThread == null || !owningThread.equals(fOwningThread.getThread());
129                         fOwningThread= ThreadMonitorManager.getDefault().getJavaMonitorThread(owningThread, null);
130                     }
131                     // update the waiting threads
132
IJavaThread[] waitingThreads= fMonitor.getWaitingThreads();
133                     if (waitingThreads == null || waitingThreads.length == 0) {
134                         // if no waiting threads, not much to do
135
changed= fWaitingThreads != null && fWaitingThreads.length != 0;
136                         fWaitingThreads= new JavaMonitorThread[0];
137                         toRemove= fOwningThread == null;
138                     } else {
139                         JavaMonitorThread[] tmp= new JavaMonitorThread[waitingThreads.length];
140                         if (changed || fWaitingThreads.length != waitingThreads.length) {
141                             // if we know it changed, we can just create the new list
142
for (int i= 0; i < waitingThreads.length; i++) {
143                                 tmp[i]= threadMonitorManager.getJavaMonitorThread(waitingThreads[i], null);
144                             }
145                             changed= true;
146                         } else {
147                             // we need to check in the new list contains the same threads as the
148
// previous list
149
int sameThread= 0;
150                             for (int i= 0; i < waitingThreads.length; i++) {
151                                 for (int j= 0; j < fWaitingThreads.length; j++) {
152                                     if (fWaitingThreads[i].getThread().equals(waitingThreads[i])) {
153                                         sameThread++;
154                                         break;
155                                     }
156                                 }
157                                 tmp[i]= threadMonitorManager.getJavaMonitorThread(waitingThreads[i], null);
158                             }
159                             changed= sameThread != waitingThreads.length;
160                         }
161                         fWaitingThreads= tmp;
162                     }
163                 } else {
164                     toRemove= true;
165                 }
166             } catch (DebugException e) {
167                 fOwningThread= null;
168                 fWaitingThreads= new JavaMonitorThread[0];
169             } finally {
170                 fToUpdate= false;
171             }
172         }
173         
174         if (toRemove) {
175             threadMonitorManager.removeJavaMonitor(this);
176         } else if (changed) {
177             fireChangeEvent(DebugEvent.CONTENT);
178         }
179         return changed;
180     }
181     
182     /**
183      * Send a change event for theJavaContendedMonitor and JavaOwnedMonitor
184      * associated with this monitor
185      */

186     private void fireChangeEvent(int detail) {
187         Object JavaDoc[] elements= fElements.toArray();
188         DebugEvent[] changeEvents= new DebugEvent[elements.length];
189         for (int i= 0; i < elements.length; i++) {
190             changeEvents[i]= new DebugEvent(elements[i], DebugEvent.CHANGE, detail);
191         }
192         DebugPlugin.getDefault().fireDebugEventSet(changeEvents);
193     }
194
195     public synchronized void setToUpdate() {
196         if (!fToUpdate) {
197             fToUpdate= true;
198             if (fOwningThread != null) {
199                 fOwningThread.setToUpdate();
200             }
201             if (fWaitingThreads != null) {
202                 for (int i= 0; i < fWaitingThreads.length; i++) {
203                     fWaitingThreads[i].setToUpdate();
204                 }
205             }
206         }
207     }
208     
209     protected void addElement(JavaOwnedMonitor monitor) {
210         fElements.add(monitor);
211     }
212     
213     protected void addElement(JavaContendedMonitor monitor) {
214         fElements.add(monitor);
215     }
216     
217     public void refresh() {
218         if (fToUpdate && !update()) {
219             if (fOwningThread != null) {
220                 fOwningThread.refresh();
221             }
222             for (int i= 0; i < fWaitingThreads.length; i++) {
223                 fWaitingThreads[i].refresh();
224             }
225         }
226     }
227     
228     /**
229      * Indicate if this monitor is currently part of a deadlock
230      */

231     public boolean isInDeadlock() {
232         return fIsInDeadlock;
233     }
234     /**
235      * Set this monitor as being part of a deadlock.
236      */

237     public void setInDeadlock(boolean isInDeadlock) {
238         boolean oldValue= fIsInDeadlock;
239         fIsInDeadlock = isInDeadlock;
240         if (oldValue != isInDeadlock) {
241             fireChangeEvent(DebugEvent.STATE);
242         }
243     }
244 }
245
Popular Tags