mirror of
https://github.com/denoland/deno.git
synced 2025-02-08 15:21:26 -05:00
fix(ext/node): UdpSocket ref and unref (#21777)
This commit is contained in:
parent
a0b6872359
commit
ad65440092
4 changed files with 89 additions and 4 deletions
|
@ -58,6 +58,7 @@ util::unit_test_factory!(
|
||||||
crypto_key_test = crypto / crypto_key_test,
|
crypto_key_test = crypto / crypto_key_test,
|
||||||
crypto_sign_test = crypto / crypto_sign_test,
|
crypto_sign_test = crypto / crypto_sign_test,
|
||||||
events_test,
|
events_test,
|
||||||
|
dgram_test,
|
||||||
fs_test,
|
fs_test,
|
||||||
http_test,
|
http_test,
|
||||||
http2_test,
|
http2_test,
|
||||||
|
|
59
cli/tests/unit_node/dgram_test.ts
Normal file
59
cli/tests/unit_node/dgram_test.ts
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
import { assertEquals } from "../../../test_util/std/assert/mod.ts";
|
||||||
|
import { execCode } from "../unit/test_util.ts";
|
||||||
|
import { createSocket } from "node:dgram";
|
||||||
|
|
||||||
|
const listenPort = 4503;
|
||||||
|
const listenPort2 = 4504;
|
||||||
|
|
||||||
|
Deno.test("[node/dgram] udp ref and unref", {
|
||||||
|
permissions: { read: true, run: true, net: true },
|
||||||
|
}, async () => {
|
||||||
|
const { promise, resolve } = Promise.withResolvers<void>();
|
||||||
|
|
||||||
|
const udpSocket = createSocket("udp4");
|
||||||
|
udpSocket.bind(listenPort);
|
||||||
|
|
||||||
|
udpSocket.unref();
|
||||||
|
udpSocket.ref();
|
||||||
|
|
||||||
|
let data;
|
||||||
|
udpSocket.on("message", (buffer, _rinfo) => {
|
||||||
|
data = Uint8Array.from(buffer);
|
||||||
|
udpSocket.close();
|
||||||
|
});
|
||||||
|
udpSocket.on("close", () => {
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
const conn = await Deno.listenDatagram({
|
||||||
|
port: listenPort2,
|
||||||
|
transport: "udp",
|
||||||
|
});
|
||||||
|
await conn.send(new Uint8Array([0, 1, 2, 3]), {
|
||||||
|
transport: "udp",
|
||||||
|
port: listenPort,
|
||||||
|
hostname: "127.0.0.1",
|
||||||
|
});
|
||||||
|
|
||||||
|
await promise;
|
||||||
|
conn.close();
|
||||||
|
assertEquals(data, new Uint8Array([0, 1, 2, 3]));
|
||||||
|
});
|
||||||
|
|
||||||
|
Deno.test("[node/dgram] udp unref", {
|
||||||
|
permissions: { read: true, run: true, net: true },
|
||||||
|
}, async () => {
|
||||||
|
const [statusCode, _output] = await execCode(`
|
||||||
|
import { createSocket } from "node:dgram";
|
||||||
|
const udpSocket = createSocket('udp4');
|
||||||
|
udpSocket.bind(${listenPort2});
|
||||||
|
// This should let the program to exit without waiting for the
|
||||||
|
// udp socket to close.
|
||||||
|
udpSocket.unref();
|
||||||
|
udpSocket.on('message', (buffer, rinfo) => {
|
||||||
|
});
|
||||||
|
`);
|
||||||
|
assertEquals(statusCode, 0);
|
||||||
|
});
|
|
@ -295,6 +295,8 @@ class Listener {
|
||||||
class Datagram {
|
class Datagram {
|
||||||
#rid = 0;
|
#rid = 0;
|
||||||
#addr = null;
|
#addr = null;
|
||||||
|
#unref = false;
|
||||||
|
#promise = null;
|
||||||
|
|
||||||
constructor(rid, addr, bufSize = 1024) {
|
constructor(rid, addr, bufSize = 1024) {
|
||||||
this.#rid = rid;
|
this.#rid = rid;
|
||||||
|
@ -367,10 +369,12 @@ class Datagram {
|
||||||
let remoteAddr;
|
let remoteAddr;
|
||||||
switch (this.addr.transport) {
|
switch (this.addr.transport) {
|
||||||
case "udp": {
|
case "udp": {
|
||||||
({ 0: nread, 1: remoteAddr } = await op_net_recv_udp(
|
this.#promise = op_net_recv_udp(
|
||||||
this.rid,
|
this.rid,
|
||||||
buf,
|
buf,
|
||||||
));
|
);
|
||||||
|
if (this.#unref) core.unrefOpPromise(this.#promise);
|
||||||
|
({ 0: nread, 1: remoteAddr } = await this.#promise);
|
||||||
remoteAddr.transport = "udp";
|
remoteAddr.transport = "udp";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -413,6 +417,20 @@ class Datagram {
|
||||||
core.close(this.rid);
|
core.close(this.rid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ref() {
|
||||||
|
this.#unref = false;
|
||||||
|
if (this.#promise !== null) {
|
||||||
|
core.refOpPromise(this.#promise);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unref() {
|
||||||
|
this.#unref = true;
|
||||||
|
if (this.#promise !== null) {
|
||||||
|
core.unrefOpPromise(this.#promise);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async *[SymbolAsyncIterator]() {
|
async *[SymbolAsyncIterator]() {
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -78,6 +78,7 @@ export class UDP extends HandleWrap {
|
||||||
|
|
||||||
#listener?: Deno.DatagramConn;
|
#listener?: Deno.DatagramConn;
|
||||||
#receiving = false;
|
#receiving = false;
|
||||||
|
#unrefed = false;
|
||||||
|
|
||||||
#recvBufferSize = UDP_DGRAM_MAXSIZE;
|
#recvBufferSize = UDP_DGRAM_MAXSIZE;
|
||||||
#sendBufferSize = UDP_DGRAM_MAXSIZE;
|
#sendBufferSize = UDP_DGRAM_MAXSIZE;
|
||||||
|
@ -273,7 +274,8 @@ export class UDP extends HandleWrap {
|
||||||
}
|
}
|
||||||
|
|
||||||
override ref() {
|
override ref() {
|
||||||
notImplemented("udp.UDP.prototype.ref");
|
this.#listener?.ref();
|
||||||
|
this.#unrefed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
send(
|
send(
|
||||||
|
@ -315,7 +317,8 @@ export class UDP extends HandleWrap {
|
||||||
}
|
}
|
||||||
|
|
||||||
override unref() {
|
override unref() {
|
||||||
notImplemented("udp.UDP.prototype.unref");
|
this.#listener?.unref();
|
||||||
|
this.#unrefed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#doBind(ip: string, port: number, _flags: number, family: number): number {
|
#doBind(ip: string, port: number, _flags: number, family: number): number {
|
||||||
|
@ -443,6 +446,10 @@ export class UDP extends HandleWrap {
|
||||||
let remoteAddr: Deno.NetAddr | null;
|
let remoteAddr: Deno.NetAddr | null;
|
||||||
let nread: number | null;
|
let nread: number | null;
|
||||||
|
|
||||||
|
if (this.#unrefed) {
|
||||||
|
this.#listener!.unref();
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
[buf, remoteAddr] = (await this.#listener!.receive(p)) as [
|
[buf, remoteAddr] = (await this.#listener!.receive(p)) as [
|
||||||
Uint8Array,
|
Uint8Array,
|
||||||
|
|
Loading…
Add table
Reference in a new issue