diff options
Diffstat (limited to 'runtime/js')
-rw-r--r-- | runtime/js/11_workers.js | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/runtime/js/11_workers.js b/runtime/js/11_workers.js index 86560b20d..c9bfc172a 100644 --- a/runtime/js/11_workers.js +++ b/runtime/js/11_workers.js @@ -139,7 +139,13 @@ class Worker extends EventTarget { #id = 0; #name = ""; - #terminated = false; + + // "RUNNING" | "CLOSED" | "TERMINATED" + // "TERMINATED" means that any controls or messages received will be + // discarded. "CLOSED" means that we have received a control + // indicating that the worker is no longer running, but there might + // still be messages left to receive. + #status = "RUNNING"; constructor(specifier, options = {}) { super(); @@ -243,17 +249,17 @@ } #pollControl = async () => { - while (!this.#terminated) { + while (this.#status === "RUNNING") { const [type, data] = await hostRecvCtrl(this.#id); // If terminate was called then we ignore all messages - if (this.#terminated) { + if (this.#status === "TERMINATED") { return; } switch (type) { case 1: { // TerminalError - this.#terminated = true; + this.#status = "CLOSED"; } /* falls through */ case 2: { // Error if (!this.#handleError(data)) { @@ -270,7 +276,7 @@ } case 3: { // Close log(`Host got "close" message from worker: ${this.#name}`); - this.#terminated = true; + this.#status = "CLOSED"; return; } default: { @@ -281,9 +287,11 @@ }; #pollMessages = async () => { - while (!this.terminated) { + while (this.#status !== "TERMINATED") { const data = await hostRecvMessage(this.#id); - if (data === null) break; + if (this.#status === "TERMINATED" || data === null) { + return; + } let message, transferables; try { const v = deserializeJsMessageData(data); @@ -332,13 +340,14 @@ } const { transfer } = options; const data = serializeJsMessageData(message, transfer); - if (this.#terminated) return; - hostPostMessage(this.#id, data); + if (this.#status === "RUNNING") { + hostPostMessage(this.#id, data); + } } terminate() { - if (!this.#terminated) { - this.#terminated = true; + if (this.#status !== "TERMINATED") { + this.#status = "TERMINATED"; hostTerminateWorker(this.#id); } } |