1) Made getVariables and evalBlock methods in PHPDBGInterface synchronized (At least...
[phpeclipse.git] / net.sourceforge.phpeclipse.debug.core / src / net / sourceforge / phpdt / internal / debug / core / PHPDBGInterface.java
index 89ef3a2..0ae3bc0 100644 (file)
@@ -179,7 +179,7 @@ public class PHPDBGInterface {
                PHPDBGFrame     DBGFrame2;
                PHPDBGFrame             DBGFrame3;
                int                     modNo;
-               
+
                DBGPacket       = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST);
                DBGFrame1       = new PHPDBGFrame (PHPDBGBase.FRAME_BPS);
                DBGFrame2       = new PHPDBGFrame (PHPDBGBase.FRAME_RAWDATA);
@@ -219,22 +219,21 @@ public class PHPDBGInterface {
                if (!condition.equals ("")) {                                                           // Do we have a condition for breakpoint
                        rawCounter++;                                                                                   // Set to new ID
                        DBGFrame1.addInt (rawCounter);                          // ID of condition
-                       
+
                        DBGFrame3.addInt (rawCounter);                                      // FRAME_RAWDATA ID
                        DBGFrame3.addInt (condition.length() + 1);                  // length of rawdata (+ null char)
                        DBGFrame3.addString (condition);                                        // The break condition
                        DBGFrame3.addChar ('\0');                                                   // null char
 
-                       DBGPacket.addFrame (DBGFrame3);                         // First add break condition            
+                       DBGPacket.addFrame (DBGFrame3);                         // First add break condition
                }
                else {
                        DBGFrame1.addInt (0);                                           // ID of condition is 0, because there is no condition
                }
 
-               
                DBGFrame1.addInt (bpno);                                            // breakpoint number
                DBGFrame1.addInt (isunderhit);                                  // is under hit
-               
+
                DBGPacket.addFrame (DBGFrame1);                                                         // Second add command data
 
                if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
@@ -419,7 +418,7 @@ public class PHPDBGInterface {
         * @param stack The stackframe for which we want the variables.
         * @return      The array of variables
         */
-       public Vector getVariables (PHPStackFrame stack) throws IOException, DebugException  {
+       public synchronized Vector getVariables (PHPStackFrame stack) throws IOException, DebugException  {
                PHPDBGPacket            DBGPacket;
                PHPDBGFrame             DBGFrame1;
                PHPDBGEvalString        evalStr;
@@ -433,7 +432,7 @@ public class PHPDBGInterface {
                DBGPacket.addFrame (DBGFrame1);                             // Add command data
 
                if (proxy.getSocket ().isClosed ()) {                       // Do we have a socket for DBG communication?
-                       return null;                                                                                    //  No, then leave here
+                       return new Vector ();                                                                   // No, then leave here with an empty vector 
                }
 
                DBGPacket.sendPacket (os);                                  // Send the request to DBG
@@ -501,7 +500,7 @@ public class PHPDBGInterface {
                flushAllPackets();
        }
 
-       public PHPVariable[] evalBlock(PHPStackFrame stack, String evalString) throws IOException, DebugException  {
+       public synchronized PHPVariable[] evalBlock(PHPStackFrame stack, String evalString) throws IOException, DebugException  {
                PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
                PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_EVAL);
                PHPDBGFrame DBGFrame2= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA);
@@ -615,7 +614,7 @@ public class PHPDBGInterface {
                                                if ((int) framesInfo[nextFrame + 8 + toRead - 1] == 0) {                                // Is there a string termination at the end?
                                                        return String.copyValueOf (framesInfo, nextFrame + 8, toRead - 1);      // Then copy frame content to String without the \0 and return
                                                }
-                                               
+
                                                return String.copyValueOf (framesInfo, nextFrame + 8, toRead);  // Copy frame content to String and return
                                        }
                                        break;
@@ -628,6 +627,75 @@ public class PHPDBGInterface {
        }
 
        /**
+        * Reset the availability flag for all stackframes in the list.
+        *
+        * @param list          The list of old stackframes
+        */
+       private void resetAvailability (Vector list) {
+               int             i;
+
+               for (i = 0; i < list.size (); i++) {
+                       ((PHPStackFrame) list.get(i)).setAvailable (false);                                     //
+               }
+       }
+
+       /**
+        * Check whether the new stackframe is in the list of old stackframes.
+        * Test for identical stackframe (identical means same description and same line number).
+        *
+        * @param stackFrameNew The stackframe to check whether he is already within the old stackframe list
+        * @param list          The list of old stackframes
+        * @return
+        *  - true if we have found the identical stackframe within the list
+        *  - false if we did not find the identical stackframe within the list
+        */
+       private boolean isStackFrameInList (PHPStackFrame stackFrameNew, Vector list) {
+               int             i;
+               PHPStackFrame   stackFrameOld;
+
+               for (i = 0; i < list.size (); i++) {
+                       stackFrameOld = (PHPStackFrame) list.get (i);                                           //
+
+                       if (stackFrameNew.getDescription ().equals (stackFrameOld.getDescription ()) &&
+                               stackFrameNew.getLineNumber () == stackFrameOld.getLineNumber ()) {     // Did we find the sent stackframe within the list of old stackframes?
+                               stackFrameOld.setAvailable (true);                                      // We found the new stackframe in the list of old stack frames
+                stackFrameOld.setIndex (stackFrameNew.getIndex ());
+                               return true;                                                            // The stackframe was found in the list
+                       }
+               }
+
+               return false;
+       }
+
+       /**
+        * Check whether the new stackframe is in the list of old stackframes.
+        * Test for exact stackframe (exact means same description and same line number).
+        *
+        * @param stackFrameNew The stackframe to check whether he is already within the old stackframe list
+        * @param list          The list of old stackframes
+        * @return
+        *  - true if we have exactly this stackframe within the list
+        *  - false if we did not find the exact stackframe within the list
+        */
+       private void markIdenticalStackFrames (Vector oldList, Vector newList) {
+               int             i;
+               PHPStackFrame   stackFrameNew;
+
+               resetAvailability (oldList);                                                    // Reset the availability flag of the old stack frames
+               resetAvailability (newList);                                                    // Reset the availability flag of the old stack frames
+
+               for (i = 0; i < newList.size (); i++) {                                                                                 // For all stackList entries
+                       stackFrameNew = (PHPStackFrame) newList.get (i);
+
+                       if (isStackFrameInList (stackFrameNew, oldList)) {                          // Is this stackframe in the list
+                               stackFrameNew.setAvailable (true);                                                                              //
+                                                                                                                                                                               //
+                               break;
+                       }
+               }
+       }
+
+       /**
         *
         * The stackList contains the currently read stackframes which were sent
         * from DBG. The DBG interface holds a list of the active stack frames.
@@ -637,10 +705,10 @@ public class PHPDBGInterface {
         * <li> It looks for new stackframes within the DBG stackframe list and
         *      adds them to the 'static' list.
         * <li> It looks for stackframes within the 'static' list, and removes them
-        *              from the 'static' list in case the do not appear within the DBG list.
+        *              from the 'static' list in case they do not appear within the DBG list.
         * <li> It looks for stackframes which are already existent and replicates the
         *              line number and the index number.
-        * <li> At the end the 'static' stackfram list has to be sorted by the stackframes
+        * <li> At the end, the 'static' stackframe list has to be sorted by the stackframes
         *              index numbers.
         * </ul>
         *
@@ -657,22 +725,32 @@ public class PHPDBGInterface {
                PHPStackFrame   stackFrameOld;
                PHPStackFrame[] newStackList;
 
+               markIdenticalStackFrames (stackListOld, stackList);                     // Check whether the newly send stack frames can be found in the list
+                                                                                                                                                               // of old stack frames
+
                for (i = 0; i < stackList.size (); i++) {                                                               // For all stackList entries
                        stackFrameNew = (PHPStackFrame) stackList.get(i);
 
                        for (n = 0; n < stackListOld.size (); n++) {                                    // For all StackFrames in the StackFrame list
                                stackFrameOld = (PHPStackFrame) stackListOld.get (n);                   //
 
-                               if (stackFrameNew.getDescription ().equals (stackFrameOld.getDescription ()) &&
-                                       stackFrameNew.getLineNumber() == stackFrameOld.getLineNumber()) {// Did we find the sent stackframe within the list of old stackframes?
+                               if (stackFrameOld.isAvailable ()) {                             // If this stack frame was already found in the new list skip it
+                                       continue;
+                               }
+
+                               if (stackFrameNew.getDescription ().equals (stackFrameOld.getDescription ())) {// Did we find the sent stackframe within the list of old stackframes?
                                        stackFrameOld.setLineNumber (stackFrameNew.getLineNumber ());
                                        stackFrameOld.setIndex (stackFrameNew.getIndex ());
 
+                                       stackFrameOld.setAvailable (true);                                                      // And mark this stack frame as available
+                                       stackFrameNew.setAvailable (true);                                                      // And mark this stack frame as available
+
                                        break;                                                                  //  Yes, then break;
                                }
                        }
 
-                       if (n == stackListOld.size ()) {                                    // Did not find the new stackframe within the list
+                       if (!stackFrameNew.isAvailable ()) {                                // Did not find the new stackframe within the list?
+                                stackFrameNew.setAvailable (true);                                                             // Mark the stack frame as available and
                                 stackListOld.add (stackFrameNew);                              //  then add the new stackframe
                        }
                }
@@ -682,13 +760,9 @@ public class PHPDBGInterface {
                for (n = 0; n < stackListOld.size (); n++) {                                            // For all StackFrames in the StackFrame list
                        stackFrameOld = (PHPStackFrame) stackListOld.get (n);                           //
 
-                       for (i = 0; i < stackList.size (); i++) {                                                       // For all stackList entries
-                               stackFrameNew = (PHPStackFrame) stackList.get (i);
-
-                               if (stackFrameNew.getDescription ().equals (stackFrameOld.getDescription ()) &&
-                                       stackFrameNew.getLineNumber() == stackFrameOld.getLineNumber()) {// Did we find the sent stackframe within the list of old stackframes?
-                                       break;                                                                  //  Yes, then break;
-                               }
+                       i = 0;
+                       if (!stackFrameOld.isAvailable ()) {
+                               i = stackList.size ();
                        }
 
                        if (i == stackList.size ()) {                                           // Did not find the old stackframe within the list of new ones