Small bug fixes for the debugger client.
[phpeclipse.git] / net.sourceforge.phpeclipse.debug.core / src / net / sourceforge / phpdt / internal / debug / core / model / PHPDebugTarget.java
index c2ffdee..c86bbbe 100644 (file)
@@ -1,14 +1,14 @@
 /**********************************************************************
-Copyright (c) 2000, 2002 IBM Corp. and others.
-All rights reserved. This program and the accompanying materials
-are made available under the terms of the Common Public License v1.0
-which accompanies this distribution, and is available at
-http://www.eclipse.org/legal/cpl-v10.html
-
-Contributors:
-    IBM Corporation - Initial implementation
-    Vicente Fernando - www.alfersoft.com.ar
-**********************************************************************/
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ Vicente Fernando - www.alfersoft.com.ar
+ **********************************************************************/
 package net.sourceforge.phpdt.internal.debug.core.model;
 
 import net.sourceforge.phpdt.internal.debug.core.PHPDBGProxy;
@@ -27,7 +27,6 @@ import org.eclipse.debug.core.model.IBreakpoint;
 import org.eclipse.debug.core.model.IDebugTarget;
 import org.eclipse.debug.core.model.IMemoryBlock;
 import org.eclipse.debug.core.model.IProcess;
-import org.eclipse.debug.core.model.IStackFrame;
 import org.eclipse.debug.core.model.IThread;
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.ui.model.IWorkbenchAdapter;
@@ -35,22 +34,51 @@ import org.eclipse.ui.model.IWorkbenchAdapter;
 /**
  * Debug target for PHP debug model.
  */
-public class PHPDebugTarget implements IPHPDebugTarget, ILaunchListener, IDebugEventSetListener {
-               
+public class PHPDebugTarget implements IPHPDebugTarget, ILaunchListener,
+               IDebugEventSetListener {
+
        private IProcess process;
-       private boolean isTerminated;
-       private boolean isSuspended;
+
        private ILaunch launch;
-       private PHPThread[] threads;
+
+       private PHPThread[] threads = new PHPThread[0];
+
        private PHPDBGProxy phpDBGProxy;
 
+       private class State {
+               private boolean isTerminated = false;
+
+               private boolean isSuspended = false;
+
+               boolean isTerminated() {
+                       return isTerminated;
+               }
+
+               boolean isSuspended() {
+                       return isSuspended;
+               }
+
+               void setTerminated(boolean terminated) {
+                       this.isTerminated = terminated;
+               }
+
+               void setSuspended(boolean suspended) {
+                       if (isTerminated())
+                               throw new IllegalStateException();
+                       this.isSuspended = suspended;
+               }
+       }
+
+       private final State state = new State();
+
        public PHPDebugTarget(ILaunch launch, IProcess process) {
-               this.isSuspended = false;
+               if (null == launch && null == process)
+                       throw new IllegalArgumentException();
                this.launch = launch;
                this.process = process;
-               this.threads = new PHPThread[0];
                // TODO XXX remove breakpoint listener at termination to avoid live leak
-               IBreakpointManager manager= DebugPlugin.getDefault().getBreakpointManager();
+               IBreakpointManager manager = DebugPlugin.getDefault()
+                               .getBreakpointManager();
                manager.addBreakpointListener(this);
                DebugPlugin.getDefault().addDebugEventListener(this);
                initialize();
@@ -58,14 +86,14 @@ public class PHPDebugTarget implements IPHPDebugTarget, ILaunchListener, IDebugE
 
        protected synchronized void initialize() {
                DebugEvent ev = new DebugEvent(this, DebugEvent.CREATE);
-               DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { ev });    
+               DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { ev });
        }
 
        public void addThread(PHPThread phpThread) {
                int i;
                PHPThread[] updatedThreads = new PHPThread[threads.length + 1];
-               
-               for(i=0; i < threads.length; i++) {
+
+               for (i = 0; i < threads.length; i++) {
                        updatedThreads[i] = threads[i];
                }
                updatedThreads[i] = phpThread;
@@ -107,9 +135,9 @@ public class PHPDebugTarget implements IPHPDebugTarget, ILaunchListener, IDebugE
        }
 
        public boolean supportsBreakpoint(IBreakpoint arg0) {
-           if(arg0.getModelIdentifier().equals(PHPDebugCorePlugin.PLUGIN_ID)) {
-            return true;
-           }
+               if (arg0.getModelIdentifier().equals(PHPDebugCorePlugin.PLUGIN_ID)) {
+                       return true;
+               }
                return false;
        }
 
@@ -125,65 +153,79 @@ public class PHPDebugTarget implements IPHPDebugTarget, ILaunchListener, IDebugE
                return launch;
        }
 
-       public boolean canTerminate() {
-               return !isTerminated;
+       public synchronized boolean canTerminate() {
+               return !isTerminated();
        }
 
-       public boolean isTerminated() {
-               return isTerminated;
+       public synchronized boolean isTerminated() {
+               return state.isTerminated();
        }
 
        public synchronized void terminate() {
-               // This method is synchronized to control a race condition between the 
-               // UI thread that terminates the debugging session, and the slave 
+               // This method is synchronized to control a race condition between the
+               // UI thread that terminates the debugging session, and the slave
                // thread that executes PHPLoop.run
-               if (isTerminated)
+               if (isTerminated())
                        // Avoid terminating twice...
                        return;
+               state.setTerminated(true);
                phpDBGProxy.stop();
                this.threads = new PHPThread[0];
-               isTerminated = true;
                fireChangeEvent();
-               IBreakpointManager manager= DebugPlugin.getDefault().getBreakpointManager();
+               IBreakpointManager manager = DebugPlugin.getDefault()
+                               .getBreakpointManager();
                manager.removeBreakpointListener(this);
                DebugPlugin.getDefault().removeDebugEventListener(this);
        }
 
-       public boolean canResume() {
-               if(isTerminated) return false;
-               return isSuspended;
+       public synchronized boolean canResume() {
+               if (isTerminated())
+                       return false;
+               return isSuspended();
        }
 
-       public boolean canSuspend() {
-               if(isTerminated) return false;
-               return !isSuspended;
+       public synchronized boolean canSuspend() {
+               if (isTerminated())
+                       return false;
+               return !isSuspended();
        }
 
-       public boolean isSuspended() {
-               return isSuspended;
+       public synchronized boolean isSuspended() {
+               return state.isSuspended();
        }
 
-       public void resume() throws DebugException {
+       public synchronized void resume() throws DebugException {
+               if (!isSuspended())
+                       return;
+               state.setSuspended(false);
                this.getPHPDBGProxy().resume();
-               isSuspended= false;
+               IThread[] threads = getThreads();
+               for (int i = 0; i < threads.length; ++i)
+                       threads[i].resume();
        }
 
-       public void suspend() throws DebugException {
+       public synchronized void suspend() throws DebugException {
+               if (isSuspended())
+                       return;
                this.getPHPDBGProxy().pause();
-               isSuspended= true;
+               state.setSuspended(true);
+               IThread[] threads = getThreads();
+               for (int i = 0; i < threads.length; ++i)
+                       threads[i].suspend();
        }
 
        public void breakpointAdded(IBreakpoint breakpoint) {
-               this.getPHPDBGProxy().addBreakpoint(breakpoint) ;
+               this.getPHPDBGProxy().addBreakpoint(breakpoint);
        }
 
        public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta arg1) {
-               this.getPHPDBGProxy().removeBreakpoint(breakpoint) ;            
+               this.getPHPDBGProxy().removeBreakpoint(breakpoint);
        }
 
        public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta arg1) {
                // is called e.g. after a line has been inserted before a breakpoint
-               // but then the debugger is out of sync with the file anyway, so debugging
+               // but then the debugger is out of sync with the file anyway, so
+               // debugging
                // should be stopped here.
        }
 
@@ -202,7 +244,8 @@ public class PHPDebugTarget implements IPHPDebugTarget, ILaunchListener, IDebugE
                return false;
        }
 
-       public IMemoryBlock getMemoryBlock(long arg0, long arg1) throws DebugException {
+       public IMemoryBlock getMemoryBlock(long arg0, long arg1)
+                       throws DebugException {
                return null;
        }
 
@@ -214,14 +257,16 @@ public class PHPDebugTarget implements IPHPDebugTarget, ILaunchListener, IDebugE
                                        IThread[] threads = getThreads();
                                        if (null != threads) {
                                                children = new Object[threads.length];
-                                               for (int i = 0; i < threads.length; ++i) 
+                                               for (int i = 0; i < threads.length; ++i)
                                                        children[i] = threads[i];
                                        }
                                        return children;
                                }
+
                                public ImageDescriptor getImageDescriptor(Object object) {
                                        return null;
                                }
+
                                public String getLabel(Object o) {
                                        String label = "(Unable to look up name... check error log)";
                                        try {
@@ -231,6 +276,7 @@ public class PHPDebugTarget implements IPHPDebugTarget, ILaunchListener, IDebugE
                                        }
                                        return label;
                                }
+
                                public Object getParent(Object o) {
                                        return PHPDebugTarget.this.getLaunch();
                                }
@@ -254,7 +300,7 @@ public class PHPDebugTarget implements IPHPDebugTarget, ILaunchListener, IDebugE
        public void setPHPDBGProxy(PHPDBGProxy phpDBGProxy) {
                this.phpDBGProxy = phpDBGProxy;
        }
-       
+
        /**
         * @see ILaunchListener#launchRemoved(ILaunch)
         */
@@ -263,24 +309,25 @@ public class PHPDebugTarget implements IPHPDebugTarget, ILaunchListener, IDebugE
                        return;
                }
                if (launch.equals(getLaunch())) {
-                       // This target has been deregistered, but it hasn't successfully terminated.
+                       // This target has been deregistered, but it hasn't successfully
+                       // terminated.
                        // Update internal state to reflect that it is disconnected
                        terminate();
                }
        }
-       
+
        /**
         * @see ILaunchListener#launchAdded(ILaunch)
         */
        public void launchAdded(ILaunch launch) {
        }
-       
+
        /**
         * @see ILaunchListener#launchChanged(ILaunch)
         */
        public void launchChanged(ILaunch launch) {
        }
-       
+
        /**
         * When a debug target or process terminates, terminate DBG Proxy.
         * 
@@ -291,10 +338,11 @@ public class PHPDebugTarget implements IPHPDebugTarget, ILaunchListener, IDebugE
                        DebugEvent event = events[i];
                        if (event.getKind() == DebugEvent.TERMINATE) {
                                Object source = event.getSource();
-                               if (source instanceof PHPDebugTarget || source instanceof IDebugTarget) {
+                               if (source instanceof PHPDebugTarget
+                                               || source instanceof IDebugTarget) {
                                        getPHPDBGProxy().stop();
-                               } else if(source instanceof IProcess) {
-                                       if(getDebugTarget().getProcess() == (IProcess)source) {
+                               } else if (source instanceof IProcess) {
+                                       if (getDebugTarget().getProcess() == (IProcess) source) {
                                                getPHPDBGProxy().stop();
                                        }
                                }
@@ -304,4 +352,3 @@ public class PHPDebugTarget implements IPHPDebugTarget, ILaunchListener, IDebugE
                }
        }
 }
-