diff options
Diffstat (limited to 'ext')
-rw-r--r-- | ext/fs/30_fs.js | 6 | ||||
-rw-r--r-- | ext/http/00_serve.js | 22 | ||||
-rw-r--r-- | ext/http/01_http.js | 27 | ||||
-rw-r--r-- | ext/kv/01_db.ts | 5 | ||||
-rw-r--r-- | ext/kv/lib.rs | 2 | ||||
-rw-r--r-- | ext/net/01_net.js | 10 | ||||
-rw-r--r-- | ext/net/lib.deno_net.d.ts | 6 | ||||
-rw-r--r-- | ext/web/00_infra.js | 7 |
8 files changed, 69 insertions, 16 deletions
diff --git a/ext/fs/30_fs.js b/ext/fs/30_fs.js index d2a656a23..830703230 100644 --- a/ext/fs/30_fs.js +++ b/ext/fs/30_fs.js @@ -34,7 +34,7 @@ import { ReadableStreamPrototype, writableStreamForRid, } from "ext:deno_web/06_streams.js"; -import { pathFromURL } from "ext:deno_web/00_infra.js"; +import { pathFromURL, SymbolDispose } from "ext:deno_web/00_infra.js"; function chmodSync(path, mode) { ops.op_fs_chmod_sync(pathFromURL(path), mode); @@ -669,6 +669,10 @@ class FsFile { } return this.#writable; } + + [SymbolDispose]() { + core.tryClose(this.rid); + } } function checkOpenOptions(options) { diff --git a/ext/http/00_serve.js b/ext/http/00_serve.js index 17a67814b..b99f28c0f 100644 --- a/ext/http/00_serve.js +++ b/ext/http/00_serve.js @@ -36,6 +36,7 @@ import { } from "ext:deno_web/06_streams.js"; import { listen, listenOptionApiName, TcpConn } from "ext:deno_net/01_net.js"; import { listenTls } from "ext:deno_net/02_tls.js"; +import { SymbolAsyncDispose } from "ext:deno_web/00_infra.js"; const { ArrayPrototypePush, ObjectHasOwn, @@ -343,6 +344,7 @@ class CallbackContext { fallbackHost; serverRid; closed; + /** @type {Promise<void> | undefined} */ closing; listener; @@ -671,22 +673,25 @@ function serveHttpOn(context, callback) { PromisePrototypeCatch(callback(req), promiseErrorHandler); } - if (!context.closed && !context.closing) { - context.closed = true; - await op_http_close(rid, false); + if (!context.closing && !context.closed) { + context.closing = op_http_close(rid, false); context.close(); } + + await context.closing; + context.close(); + context.closed = true; })(); return { finished, async shutdown() { - if (!context.closed && !context.closing) { + if (!context.closing && !context.closed) { // Shut this HTTP server down gracefully - context.closing = true; - await op_http_close(context.serverRid, true); - context.closed = true; + context.closing = op_http_close(context.serverRid, true); } + await context.closing; + context.closed = true; }, ref() { ref = true; @@ -700,6 +705,9 @@ function serveHttpOn(context, callback) { core.unrefOp(currentPromise[promiseIdSymbol]); } }, + [SymbolAsyncDispose]() { + return this.shutdown(); + }, }; } diff --git a/ext/http/01_http.js b/ext/http/01_http.js index 705e616e4..cfe0f710e 100644 --- a/ext/http/01_http.js +++ b/ext/http/01_http.js @@ -44,6 +44,7 @@ import { ReadableStreamPrototype, } from "ext:deno_web/06_streams.js"; import { serve } from "ext:deno_http/00_serve.js"; +import { SymbolDispose } from "ext:deno_web/00_infra.js"; const { ArrayPrototypeIncludes, ArrayPrototypeMap, @@ -69,6 +70,9 @@ const { const connErrorSymbol = Symbol("connError"); const _deferred = Symbol("upgradeHttpDeferred"); +/** @type {(self: HttpConn, rid: number) => boolean} */ +let deleteManagedResource; + class HttpConn { #rid = 0; #closed = false; @@ -79,7 +83,12 @@ class HttpConn { // that were created during lifecycle of this request. // When the connection is closed these resources should be closed // as well. - managedResources = new SafeSet(); + #managedResources = new SafeSet(); + + static { + deleteManagedResource = (self, rid) => + SetPrototypeDelete(self.#managedResources, rid); + } constructor(rid, remoteAddr, localAddr) { this.#rid = rid; @@ -123,7 +132,7 @@ class HttpConn { } const { 0: streamRid, 1: method, 2: url } = nextRequest; - SetPrototypeAdd(this.managedResources, streamRid); + SetPrototypeAdd(this.#managedResources, streamRid); /** @type {ReadableStream<Uint8Array> | undefined} */ let body = null; @@ -167,13 +176,21 @@ class HttpConn { if (!this.#closed) { this.#closed = true; core.close(this.#rid); - for (const rid of new SafeSetIterator(this.managedResources)) { - SetPrototypeDelete(this.managedResources, rid); + for (const rid of new SafeSetIterator(this.#managedResources)) { + SetPrototypeDelete(this.#managedResources, rid); core.close(rid); } } } + [SymbolDispose]() { + core.tryClose(this.#rid); + for (const rid of new SafeSetIterator(this.#managedResources)) { + SetPrototypeDelete(this.#managedResources, rid); + core.tryClose(rid); + } + } + [SymbolAsyncIterator]() { // deno-lint-ignore no-this-alias const httpConn = this; @@ -395,7 +412,7 @@ function createRespondWith( abortController.abort(error); throw error; } finally { - if (SetPrototypeDelete(httpConn.managedResources, streamRid)) { + if (deleteManagedResource(httpConn, streamRid)) { core.close(streamRid); } } diff --git a/ext/kv/01_db.ts b/ext/kv/01_db.ts index 6e8a571f0..34678261a 100644 --- a/ext/kv/01_db.ts +++ b/ext/kv/01_db.ts @@ -12,6 +12,7 @@ const { SymbolToStringTag, Uint8ArrayPrototype, } = globalThis.__bootstrap.primordials; +import { SymbolDispose } from "ext:deno_web/00_infra.js"; const core = Deno.core; const ops = core.ops; @@ -299,6 +300,10 @@ class Kv { close() { core.close(this.#rid); } + + [SymbolDispose]() { + core.tryClose(this.#rid); + } } class AtomicOperation { diff --git a/ext/kv/lib.rs b/ext/kv/lib.rs index 9e2273108..d357a2927 100644 --- a/ext/kv/lib.rs +++ b/ext/kv/lib.rs @@ -66,7 +66,7 @@ const MAX_TOTAL_MUTATION_SIZE_BYTES: usize = 800 * 1024; const MAX_TOTAL_KEY_SIZE_BYTES: usize = 80 * 1024; deno_core::extension!(deno_kv, - deps = [ deno_console ], + deps = [ deno_console, deno_web ], parameters = [ DBH: DatabaseHandler ], ops = [ op_kv_database_open<DBH>, diff --git a/ext/net/01_net.js b/ext/net/01_net.js index f2bf5e7df..05aca07e5 100644 --- a/ext/net/01_net.js +++ b/ext/net/01_net.js @@ -9,6 +9,8 @@ import { writableStreamForRid, } from "ext:deno_web/06_streams.js"; import * as abortSignal from "ext:deno_web/03_abort_signal.js"; +import { SymbolDispose } from "ext:deno_web/00_infra.js"; + const primordials = globalThis.__bootstrap.primordials; const { ArrayPrototypeFilter, @@ -160,6 +162,10 @@ class Conn { (id) => core.unrefOp(id), ); } + + [SymbolDispose]() { + core.tryClose(this.#rid); + } } class TcpConn extends Conn { @@ -249,6 +255,10 @@ class Listener { core.close(this.rid); } + [SymbolDispose]() { + core.tryClose(this.#rid); + } + [SymbolAsyncIterator]() { return this; } diff --git a/ext/net/lib.deno_net.d.ts b/ext/net/lib.deno_net.d.ts index 030157d63..79e15563a 100644 --- a/ext/net/lib.deno_net.d.ts +++ b/ext/net/lib.deno_net.d.ts @@ -2,6 +2,7 @@ /// <reference no-default-lib="true" /> /// <reference lib="esnext" /> +/// <reference lib="esnext.disposable" /> declare namespace Deno { /** @category Network */ @@ -24,7 +25,8 @@ declare namespace Deno { * * @category Network */ - export interface Listener<T extends Conn = Conn> extends AsyncIterable<T> { + export interface Listener<T extends Conn = Conn> + extends AsyncIterable<T>, Disposable { /** Waits for and resolves to the next connection to the `Listener`. */ accept(): Promise<T>; /** Close closes the listener. Any pending accept promises will be rejected @@ -57,7 +59,7 @@ declare namespace Deno { export type TlsListener = Listener<TlsConn>; /** @category Network */ - export interface Conn extends Reader, Writer, Closer { + export interface Conn extends Reader, Writer, Closer, Disposable { /** The local address of the connection. */ readonly localAddr: Addr; /** The remote address of the connection. */ diff --git a/ext/web/00_infra.js b/ext/web/00_infra.js index e9d5dd48b..441081604 100644 --- a/ext/web/00_infra.js +++ b/ext/web/00_infra.js @@ -32,6 +32,7 @@ const { StringPrototypeSubstring, StringPrototypeToLowerCase, StringPrototypeToUpperCase, + Symbol, TypeError, } = primordials; import { URLPrototype } from "ext:deno_url/00_url.js"; @@ -458,6 +459,12 @@ function pathFromURL(pathOrUrl) { // it in unit tests internals.pathFromURL = pathFromURL; +// deno-lint-ignore prefer-primordials +export const SymbolDispose = Symbol.dispose ?? Symbol("Symbol.dispose"); +// deno-lint-ignore prefer-primordials +export const SymbolAsyncDispose = Symbol.asyncDispose ?? + Symbol("Symbol.asyncDispose"); + export { ASCII_ALPHA, ASCII_ALPHANUMERIC, |