Bug 1300036 - Update the state correctly on the client side when the server reports a conflict on resume. r=ejpbruel
authorAlexandre Poirot <poirot.alex@gmail.com>
Mon, 05 Sep 2016 10:42:05 -0700
changeset 355268 73f77b885f17cb75069196258a6448490b543d15
parent 355267 d9a19f976f1e30e01b240372099098e67c167603
child 355269 6a8bf7596f42d22961f4d79f1cd8b282618dafb5
push id6570
push userraliiev@mozilla.com
push dateMon, 14 Nov 2016 12:26:13 +0000
treeherdermozilla-beta@f455459b2ae5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersejpbruel
bugs1300036
milestone51.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1300036 - Update the state correctly on the client side when the server reports a conflict on resume. r=ejpbruel 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