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.
This commit is contained in:
Joey Mezzacappa 2022-08-15 16:09:45 -04:00 committed by GitHub
parent 7ab26e175e
commit 62d967bce0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 8 deletions

View file

@ -698,16 +698,28 @@ V86Starter.prototype.run = async function()
*/ */
V86Starter.prototype.stop = 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 * @ignore
* @export * @export
*/ */
V86Starter.prototype.destroy = function() V86Starter.prototype.destroy = async function()
{ {
this.stop(); await this.stop();
this.v86.destroy(); this.v86.destroy();
this.keyboard_adapter && this.keyboard_adapter.destroy(); this.keyboard_adapter && this.keyboard_adapter.destroy();

View file

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