Compare commits

...

2 commits

Author SHA1 Message Date
2aeba659ed also wait for reset
(move null assignment to after the process is definitely killed, so that we can actually perform the dispose op)

v0.3.1
2024-11-02 11:44:49 -04:00
d4b316962a Wait for the state to become stopped in QemuVM#Stop 2024-11-02 11:35:47 -04:00

View file

@ -89,7 +89,7 @@ export class QemuVM extends EventEmitter {
// Fall back to the default process launcher. This is
// done so we can have our cake (compatibility) and eat it too
// (do this fun process abstraction stuff for whatever really)
if(!processLauncher) {
if (!processLauncher) {
this.qemuLauncher = new DefaultProcessLauncher();
} else {
this.qemuLauncher = processLauncher;
@ -144,7 +144,6 @@ export class QemuVM extends EventEmitter {
};
}
this.definition.command = cmd;
this.addedAdditionalArguments = true;
}
@ -160,19 +159,42 @@ export class QemuVM extends EventEmitter {
await this.MonitorCommand('system_reset');
}
async Stop() {
async Stop(): Promise<void> {
this.AssertState(VMState.Started, 'cannot use QemuVM#Stop on a non-started VM');
// I'm not sure this is better, but I'm also not sure it should be an assertion
//if(this.state !== VMState.Started)
// return;
// Indicate we're stopping, so we don't erroneously start trying to restart everything we're going to tear down.
this.SetState(VMState.Stopping);
// Stop the QEMU process, which will bring down everything else.
await this.StopQemu();
// Wait for the VM to reach the stopped state.
return new Promise((res, rej) => {
this.once('statechange', (state) => {
if (state == VMState.Stopped) res();
});
});
}
async Reset() {
async Reset(): Promise<void> {
this.AssertState(VMState.Started, 'cannot use QemuVM#Reset on a non-started VM');
await this.StopQemu();
let self = this;
// Wait for the VM to regain the started state
return new Promise((res, rej) => {
let cb = (state: VMState) => {
if (state == VMState.Started) {
this.removeListener('statechange', cb);
res();
}
};
this.on('statechange', cb);
});
}
async QmpCommand(command: string, args: any | null): Promise<any> {
@ -266,6 +288,7 @@ export class QemuVM extends EventEmitter {
// Dispose events. StartQemu() will assign them again to the new process.
// A bit mucky but /shrug.
self.qemuProcess?.dispose();
self.qemuProcess = null;
self.qmpInstance.reset();
self.qmpInstance.setWriter(null);
@ -285,10 +308,12 @@ export class QemuVM extends EventEmitter {
// Note that we've already tore down everything upon entry to this event handler; therefore
// we can simply set the state and move on.
this.SetState(VMState.Stopped);
self.qemuProcess = null;
}
} else {
// Indicate we have stopped.
this.SetState(VMState.Stopped);
self.qemuProcess = null;
}
});
}
@ -296,7 +321,6 @@ export class QemuVM extends EventEmitter {
private async StopQemu() {
if (this.qemuProcess) {
this.qemuProcess?.kill('SIGTERM');
this.qemuProcess = null;
}
}