feat: disposable Deno resources (#20845)

This commit implements Symbol.dispose and Symbol.asyncDispose for
the relevant resources.

Closes #20839

---------

Signed-off-by: Bartek Iwańczuk <biwanczuk@gmail.com>
Co-authored-by: Bartek Iwańczuk <biwanczuk@gmail.com>
This commit is contained in:
Luca Casonato 2023-11-01 20:26:12 +01:00 committed by GitHub
parent 1d19b1011b
commit d42f154312
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 342 additions and 35 deletions

View file

@ -18,7 +18,11 @@ const {
} = primordials;
import { FsFile } from "ext:deno_fs/30_fs.js";
import { readAll } from "ext:deno_io/12_io.js";
import { assert, pathFromURL } from "ext:deno_web/00_infra.js";
import {
assert,
pathFromURL,
SymbolAsyncDispose,
} from "ext:deno_web/00_infra.js";
import * as abortSignal from "ext:deno_web/03_abort_signal.js";
import {
readableStreamCollectIntoUint8Array,
@ -201,7 +205,6 @@ class ChildProcess {
#rid;
#waitPromiseId;
#waitComplete = false;
#unrefed = false;
#pid;
get pid() {
@ -216,7 +219,6 @@ class ChildProcess {
return this.#stdin;
}
#stdoutRid;
#stdout = null;
get stdout() {
if (this.#stdout == null) {
@ -225,7 +227,6 @@ class ChildProcess {
return this.#stdout;
}
#stderrRid;
#stderr = null;
get stderr() {
if (this.#stderr == null) {
@ -254,12 +255,10 @@ class ChildProcess {
}
if (stdoutRid !== null) {
this.#stdoutRid = stdoutRid;
this.#stdout = readableStreamForRidUnrefable(stdoutRid);
}
if (stderrRid !== null) {
this.#stderrRid = stderrRid;
this.#stderr = readableStreamForRidUnrefable(stderrRid);
}
@ -324,15 +323,22 @@ class ChildProcess {
ops.op_spawn_kill(this.#rid, signo);
}
async [SymbolAsyncDispose]() {
try {
ops.op_spawn_kill(this.#rid, "SIGTERM");
} catch {
// ignore errors from killing the process (such as ESRCH or BadResource)
}
await this.#status;
}
ref() {
this.#unrefed = false;
core.refOp(this.#waitPromiseId);
if (this.#stdout) readableStreamForRidUnrefableRef(this.#stdout);
if (this.#stderr) readableStreamForRidUnrefableRef(this.#stderr);
}
unref() {
this.#unrefed = true;
core.unrefOp(this.#waitPromiseId);
if (this.#stdout) readableStreamForRidUnrefableUnref(this.#stdout);
if (this.#stderr) readableStreamForRidUnrefableUnref(this.#stderr);