Browse Source

Wait for emulation to stop when destroying (#721)

In some environments, the "emulator-stopped" event did not always fire
when calling the `destroy()` method. This waits for emulation to finish
stopping before continuing with the rest of the destructor.

When stopping the emulator with `.stop()`, the `v86` instance's state
would follow these transitions:

1. Before calling `.stop()`:
   ```js
   {
     running: true,
     stopped: false
   }
   ```
2. Immediately after calling `.stop()`:
   ```js
   {
     running: true,
     stopped: true
   }
   ```
3. After the emulator has finished stopping:
   ```js
   {
     running: false,
     stopped: false
   }
   ```

It was not immediately obvious how properties named `running` and
`stopped` could ever have the same values. This commit renames `stopped`
to `stopping` so it is slightly easier to understand while debugging.
Joey Mezzacappa 1 year ago
parent
commit
62d967bce0
2 changed files with 20 additions and 8 deletions
  1. 15 3
      src/browser/starter.js
  2. 5 5
      src/main.js

+ 15 - 3
src/browser/starter.js

@@ -698,16 +698,28 @@ V86Starter.prototype.run = async function()
  */
 V86Starter.prototype.stop = async function()
 {
-    this.bus.send("cpu-stop");
+    if(!this.cpu_is_running)
+    {
+        return;
+    }
+
+    await new Promise(resolve => {
+        const listener = () => {
+            this.remove_listener("emulator-stopped", listener);
+            resolve();
+        };
+        this.add_listener("emulator-stopped", listener);
+        this.bus.send("cpu-stop");
+    });
 };
 
 /**
  * @ignore
  * @export
  */
-V86Starter.prototype.destroy = function()
+V86Starter.prototype.destroy = async function()
 {
-    this.stop();
+    await this.stop();
 
     this.v86.destroy();
     this.keyboard_adapter && this.keyboard_adapter.destroy();

+ 5 - 5
src/main.js

@@ -10,7 +10,7 @@ function v86(bus, wasm)
     this.running = false;
 
     /** @type {boolean} */
-    this.stopped = false;
+    this.stopping = false;
 
     this.tick_counter = 0;
     this.worker = null;
@@ -29,7 +29,7 @@ function v86(bus, wasm)
 
 v86.prototype.run = function()
 {
-    this.stopped = false;
+    this.stopping = false;
 
     if(!this.running)
     {
@@ -42,9 +42,9 @@ v86.prototype.run = function()
 
 v86.prototype.do_tick = function()
 {
-    if(this.stopped || !this.running)
+    if(this.stopping || !this.running)
     {
-        this.stopped = this.running = false;
+        this.stopping = this.running = false;
         this.bus.send("emulator-stopped");
         return;
     }
@@ -74,7 +74,7 @@ v86.prototype.stop = function()
 {
     if(this.running)
     {
-        this.stopped = true;
+        this.stopping = true;
     }
 };