Bug 1300036 - Update the state correctly on the client side when the server reports a conflict on resume. r=jlongster draft
authorAlexandre Poirot <poirot.alex@gmail.com>
Mon, 05 Sep 2016 10:42:05 -0700
changeset 410115 2a48e80966e4993f6d445c2249bc3344dc76ebfe
parent 409920 a5b86174eb3d486408c4abce8f34816455e3bff9
child 530502 fc9763e332f3f46c204b80401e4607177f198843
push id28650
push userbmo:poirot.alex@gmail.com
push dateTue, 06 Sep 2016 08:57:26 +0000
reviewersjlongster
bugs1300036
milestone51.0a1
Bug 1300036 - Update the state correctly on the client side when the server reports a conflict on resume. r=jlongster MozReview-Commit-ID: IK6LXEGXan
devtools/server/actors/script.js
devtools/shared/client/main.js
--- a/devtools/server/actors/script.js
+++ b/devtools/server/actors/script.js
@@ -978,17 +978,18 @@ const ThreadActor = ActorClassWithSpec(t
   /**
    * Handle a protocol request to resume execution of the debuggee.
    */
   onResume: function (aRequest) {
     if (this._state !== "paused") {
       return {
         error: "wrongState",
         message: "Can't resume when debuggee isn't paused. Current state is '"
-          + this._state + "'"
+          + this._state + "'",
+        state: this._state
       };
     }
 
     // In case of multiple nested event loops (due to multiple debuggers open in
     // different tabs or multiple debugger clients connected to the same tab)
     // only allow resumption in a LIFO order.
     if (this._nestedEventLoops.size && this._nestedEventLoops.lastPausedUrl
         && (this._nestedEventLoops.lastPausedUrl !== this._parent.url
--- a/devtools/shared/client/main.js
+++ b/devtools/shared/client/main.js
@@ -140,17 +140,18 @@ function eventSource(aProto) {
 
 /**
  * Set of protocol messages that affect thread state, and the
  * state the actor is in after each message.
  */
 const ThreadStateTypes = {
   "paused": "paused",
   "resumed": "attached",
-  "detached": "detached"
+  "detached": "detached",
+  "running": "attached"
 };
 
 /**
  * Set of protocol messages that are sent by the server without a prior request
  * by the client.
  */
 const UnsolicitedNotifications = {
   "consoleAPICall": "consoleAPICall",
@@ -1734,34 +1735,42 @@ ThreadClient.prototype = {
     type: "resume",
     resumeLimit: args(0)
   }, {
     before: function (aPacket) {
       this._assertPaused("resume");
 
       // Put the client in a tentative "resuming" state so we can prevent
       // further requests that should only be sent in the paused state.
+      this._previousState = this._state;
       this._state = "resuming";
 
       if (this._pauseOnExceptions) {
         aPacket.pauseOnExceptions = this._pauseOnExceptions;
       }
       if (this._ignoreCaughtExceptions) {
         aPacket.ignoreCaughtExceptions = this._ignoreCaughtExceptions;
       }
       if (this._pauseOnDOMEvents) {
         aPacket.pauseOnDOMEvents = this._pauseOnDOMEvents;
       }
       return aPacket;
     },
     after: function (aResponse) {
-      if (aResponse.error) {
-        // There was an error resuming, back to paused state.
-        this._state = "paused";
+      if (aResponse.error && this._state == "resuming") {
+        // There was an error resuming, update the state to the new one
+        // reported by the server, if given (only on wrongState), otherwise
+        // reset back to the previous state.
+        if (aResponse.state) {
+          this._state = ThreadStateTypes[aResponse.state];
+        } else {
+          this._state = this._previousState;
+        }
       }
+      delete this._previousState;
       return aResponse;
     },
   }),
 
   /**
    * Reconfigure the thread actor.
    *
    * @param object aOptions