1 11 package org.eclipse.debug.core.model; 12 13 14 import java.util.HashMap ; 15 import java.util.Iterator ; 16 import java.util.Map ; 17 18 import org.eclipse.core.runtime.IStatus; 19 import org.eclipse.core.runtime.PlatformObject; 20 import org.eclipse.core.runtime.Status; 21 import org.eclipse.debug.core.DebugEvent; 22 import org.eclipse.debug.core.DebugException; 23 import org.eclipse.debug.core.DebugPlugin; 24 import org.eclipse.debug.core.ILaunch; 25 import org.eclipse.debug.core.ILaunchConfiguration; 26 import org.eclipse.debug.internal.core.DebugCoreMessages; 27 import org.eclipse.debug.internal.core.NullStreamsProxy; 28 import org.eclipse.debug.internal.core.StreamsProxy; 29 30 31 45 public class RuntimeProcess extends PlatformObject implements IProcess { 46 47 private static final int MAX_WAIT_FOR_DEATH_ATTEMPTS = 10; 48 private static final int TIME_TO_WAIT_FOR_THREAD_DEATH = 500; 50 53 private ILaunch fLaunch; 54 55 58 private Process fProcess; 59 60 63 private int fExitValue; 64 65 69 private ProcessMonitorThread fMonitor; 70 71 74 private IStreamsProxy fStreamsProxy; 75 76 79 private String fName; 80 81 84 private boolean fTerminated; 85 86 89 private Map fAttributes; 90 91 94 private boolean fCaptureOutput = true; 95 96 107 public RuntimeProcess(ILaunch launch, Process process, String name, Map attributes) { 108 setLaunch(launch); 109 initializeAttributes(attributes); 110 fProcess= process; 111 fName= name; 112 fTerminated= true; 113 try { 114 process.exitValue(); 115 } catch (IllegalThreadStateException e) { 116 fTerminated= false; 117 } 118 119 String captureOutput = launch.getAttribute(DebugPlugin.ATTR_CAPTURE_OUTPUT); 120 fCaptureOutput = !("false".equals(captureOutput)); 122 fStreamsProxy= createStreamsProxy(); 123 fMonitor = new ProcessMonitorThread(this); 124 fMonitor.start(); 125 launch.addProcess(this); 126 fireCreationEvent(); 127 } 128 129 134 private void initializeAttributes(Map attributes) { 135 if (attributes != null) { 136 Iterator keys = attributes.keySet().iterator(); 137 while (keys.hasNext()) { 138 String key = (String )keys.next(); 139 setAttribute(key, (String )attributes.get(key)); 140 } 141 } 142 } 143 144 147 public boolean canTerminate() { 148 return !fTerminated; 149 } 150 151 154 public String getLabel() { 155 return fName; 156 } 157 158 163 protected void setLaunch(ILaunch launch) { 164 fLaunch = launch; 165 } 166 167 170 public ILaunch getLaunch() { 171 return fLaunch; 172 } 173 174 179 protected Process getSystemProcess() { 180 return fProcess; 181 } 182 183 186 public boolean isTerminated() { 187 return fTerminated; 188 } 189 190 193 public void terminate() throws DebugException { 194 if (!isTerminated()) { 195 if (fStreamsProxy instanceof StreamsProxy) { 196 ((StreamsProxy)fStreamsProxy).kill(); 197 } 198 Process process = getSystemProcess(); 199 if (process != null) { 200 process.destroy(); 201 } 202 int attempts = 0; 203 while (attempts < MAX_WAIT_FOR_DEATH_ATTEMPTS) { 204 try { 205 process = getSystemProcess(); 206 if (process != null) { 207 fExitValue = process.exitValue(); } 209 return; 210 } catch (IllegalThreadStateException ie) { 211 } 212 try { 213 Thread.sleep(TIME_TO_WAIT_FOR_THREAD_DEATH); 214 } catch (InterruptedException e) { 215 } 216 attempts++; 217 } 218 if (fMonitor != null) { 220 fMonitor.killThread(); 221 fMonitor = null; 222 } 223 IStatus status = new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), DebugException.TARGET_REQUEST_FAILED, DebugCoreMessages.RuntimeProcess_terminate_failed, null); 224 throw new DebugException(status); 225 } 226 } 227 228 232 protected void terminated() { 233 if (fStreamsProxy instanceof StreamsProxy) { 234 ((StreamsProxy)fStreamsProxy).close(); 235 } 236 fTerminated= true; 237 try { 238 fExitValue = fProcess.exitValue(); 239 } catch (IllegalThreadStateException ie) { 240 } 241 fProcess= null; 242 fireTerminateEvent(); 243 } 244 245 248 public IStreamsProxy getStreamsProxy() { 249 if (!fCaptureOutput) { 250 return null; 251 } 252 return fStreamsProxy; 253 } 254 255 260 protected IStreamsProxy createStreamsProxy() { 261 if (!fCaptureOutput) { 262 return new NullStreamsProxy(getSystemProcess()); 263 } 264 String encoding = getLaunch().getAttribute(DebugPlugin.ATTR_CONSOLE_ENCODING); 265 return new StreamsProxy(getSystemProcess(), encoding); 266 } 267 268 271 protected void fireCreationEvent() { 272 fireEvent(new DebugEvent(this, DebugEvent.CREATE)); 273 } 274 275 280 protected void fireEvent(DebugEvent event) { 281 DebugPlugin manager= DebugPlugin.getDefault(); 282 if (manager != null) { 283 manager.fireDebugEventSet(new DebugEvent[]{event}); 284 } 285 } 286 287 290 protected void fireTerminateEvent() { 291 fireEvent(new DebugEvent(this, DebugEvent.TERMINATE)); 292 } 293 294 297 protected void fireChangeEvent() { 298 fireEvent(new DebugEvent(this, DebugEvent.CHANGE)); 299 } 300 301 304 public void setAttribute(String key, String value) { 305 if (fAttributes == null) { 306 fAttributes = new HashMap (5); 307 } 308 Object origVal = fAttributes.get(key); 309 if (origVal != null && origVal.equals(value)) { 310 return; } 312 313 fAttributes.put(key, value); 314 fireChangeEvent(); 315 } 316 317 320 public String getAttribute(String key) { 321 if (fAttributes == null) { 322 return null; 323 } 324 return (String )fAttributes.get(key); 325 } 326 327 330 public Object getAdapter(Class adapter) { 331 if (adapter.equals(IProcess.class)) { 332 return this; 333 } 334 if (adapter.equals(IDebugTarget.class)) { 335 ILaunch launch = getLaunch(); 336 IDebugTarget[] targets = launch.getDebugTargets(); 337 for (int i = 0; i < targets.length; i++) { 338 if (this.equals(targets[i].getProcess())) { 339 return targets[i]; 340 } 341 } 342 return null; 343 } 344 if (adapter.equals(ILaunch.class)) { 345 return getLaunch(); 346 } 347 if(adapter.equals(ILaunchConfiguration.class)) { 349 return getLaunch().getLaunchConfiguration(); 350 } 351 return super.getAdapter(adapter); 352 } 353 356 public int getExitValue() throws DebugException { 357 if (isTerminated()) { 358 return fExitValue; 359 } 360 throw new DebugException(new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), DebugException.TARGET_REQUEST_FAILED, DebugCoreMessages.RuntimeProcess_Exit_value_not_available_until_process_terminates__1, null)); 361 } 362 363 367 class ProcessMonitorThread extends Thread { 368 369 372 protected boolean fExit; 373 376 protected Process fOSProcess; 377 381 protected RuntimeProcess fRuntimeProcess; 382 383 386 protected Thread fThread; 387 388 391 private final Object fThreadLock = new Object (); 392 393 396 public void run() { 397 synchronized (fThreadLock) { 398 if (fExit) { 399 return; 400 } 401 fThread = Thread.currentThread(); 402 } 403 while (fOSProcess != null) { 404 try { 405 fOSProcess.waitFor(); 406 } catch (InterruptedException ie) { 407 Thread.interrupted(); 409 } finally { 410 fOSProcess = null; 411 fRuntimeProcess.terminated(); 412 } 413 } 414 fThread = null; 415 } 416 417 423 public ProcessMonitorThread(RuntimeProcess process) { 424 super(DebugCoreMessages.ProcessMonitorJob_0); 425 setDaemon(true); 426 fRuntimeProcess= process; 427 fOSProcess= process.getSystemProcess(); 428 } 429 430 437 protected void killThread() { 438 synchronized (fThreadLock) { 439 if (fThread == null) { 440 fExit = true; 441 } else { 442 fThread.interrupt(); 443 } 444 } 445 } 446 } 447 } 448 | Popular Tags |