Skip to content

Commit 364c85e

Browse files
committed
quic: stream fixes
1 parent 5536044 commit 364c85e

File tree

1 file changed

+36
-74
lines changed

1 file changed

+36
-74
lines changed

lib/internal/quic/core.js

Lines changed: 36 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -2601,59 +2601,45 @@ class QuicStream extends Duplex {
26012601
this._readableState.readingMore = true;
26022602
this.on('pause', streamOnPause);
26032603

2604-
// See src/node_quic_stream.h for an explanation
2605-
// of the initial states for unidirectional streams.
2606-
if (this.unidirectional) {
2607-
if (session instanceof QuicServerSession) {
2608-
if (this.serverInitiated) {
2609-
// Close the readable side
2610-
this.push(null);
2611-
this.read();
2612-
} else {
2613-
// Close the writable side
2614-
this.end();
2615-
}
2616-
} else if (this.serverInitiated) {
2617-
// Close the writable side
2618-
this.end();
2619-
} else {
2620-
this.push(null);
2621-
this.read();
2622-
}
2623-
}
2624-
26252604
// The QuicStream writes are corked until kSetHandle
26262605
// is set, ensuring that writes are buffered in JavaScript
26272606
// until we have somewhere to send them.
26282607
this.cork();
26292608
}
26302609

2631-
// Set handle is called once the QuicSession has been able
2632-
// to complete creation of the internal QuicStream handle.
2633-
// This will happen only after the QuicSession's own
2634-
// internal handle has been created. The QuicStream object
2635-
// is still minimally usable before this but any data
2636-
// written will be buffered until kSetHandle is called.
2637-
[kSetHandle](handle) {
2638-
this[kHandle] = handle;
2639-
if (handle !== undefined) {
2640-
handle.onread = onStreamRead;
2641-
handle[owner_symbol] = this;
2642-
this[async_id_symbol] = handle.getAsyncId();
2643-
this.#id = handle.id();
2644-
this.#dataRateHistogram = new Histogram(handle.rate);
2645-
this.#dataSizeHistogram = new Histogram(handle.size);
2646-
this.#dataAckHistogram = new Histogram(handle.ack);
2647-
this.uncork();
2648-
this.emit('ready');
2649-
} else {
2650-
if (this.#dataRateHistogram)
2651-
this.#dataRateHistogram[kDestroyHistogram]();
2652-
if (this.#dataSizeHistogram)
2653-
this.#dataSizeHistogram[kDestroyHistogram]();
2654-
if (this.#dataAckHistogram)
2655-
this.#dataAckHistogram[kDestroyHistogram]();
2656-
}
2610+
_construct(cb) {
2611+
// Set handle is called once the QuicSession has been able
2612+
// to complete creation of the internal QuicStream handle.
2613+
// This will happen only after the QuicSession's own
2614+
// internal handle has been created. The QuicStream object
2615+
// is still minimally usable before this but any data
2616+
// written will be buffered until kSetHandle is called.
2617+
this[kSetHandle] = (handle) => {
2618+
this[kHandle] = handle;
2619+
if (handle !== undefined) {
2620+
handle.onread = onStreamRead;
2621+
handle[owner_symbol] = this;
2622+
this[async_id_symbol] = handle.getAsyncId();
2623+
this.#id = handle.id();
2624+
this.#dataRateHistogram = new Histogram(handle.rate);
2625+
this.#dataSizeHistogram = new Histogram(handle.size);
2626+
this.#dataAckHistogram = new Histogram(handle.ack);
2627+
this.uncork();
2628+
2629+
this.emit('ready');
2630+
// TODO (fix): What happens on failure? We still need to
2631+
// invoke the callback somehow? Change signature of kSetHandle
2632+
// to (err, handle)?
2633+
cb();
2634+
} else {
2635+
if (this.#dataRateHistogram)
2636+
this.#dataRateHistogram[kDestroyHistogram]();
2637+
if (this.#dataSizeHistogram)
2638+
this.#dataSizeHistogram[kDestroyHistogram]();
2639+
if (this.#dataAckHistogram)
2640+
this.#dataAckHistogram[kDestroyHistogram]();
2641+
}
2642+
};
26572643
}
26582644

26592645
[kStreamReset](code) {
@@ -2700,6 +2686,7 @@ class QuicStream extends Duplex {
27002686
if (this.destroyed || this.#closed)
27012687
return;
27022688

2689+
// TODO: This will deadlock on failure?
27032690
if (this.pending)
27042691
return this.once('ready', () => this[kClose](family, code));
27052692

@@ -2785,19 +2772,6 @@ class QuicStream extends Duplex {
27852772
}
27862773

27872774
#writeGeneric = function(writev, data, encoding, cb) {
2788-
if (this.destroyed)
2789-
return; // TODO(addaleax): Can this happen?
2790-
2791-
// The stream should be corked while still pending
2792-
// but just in case uncork
2793-
// was called early, defer the actual write until the
2794-
// ready event is emitted.
2795-
if (this.pending) {
2796-
return this.once('ready', () => {
2797-
this.#writeGeneric(writev, data, encoding, cb);
2798-
});
2799-
}
2800-
28012775
this[kUpdateTimer]();
28022776
const req = (writev) ?
28032777
writevGeneric(this, data, cb) :
@@ -2821,13 +2795,6 @@ class QuicStream extends Duplex {
28212795
// coming so that a fin stream packet can be
28222796
// sent.
28232797
_final(cb) {
2824-
// The QuicStream should be corked while pending
2825-
// so this shouldn't be called, but just in case
2826-
// the stream was prematurely uncorked, defer the
2827-
// operation until the ready event is emitted.
2828-
if (this.pending)
2829-
return this.once('ready', () => this._final(cb));
2830-
28312798
const handle = this[kHandle];
28322799
if (handle === undefined) {
28332800
cb();
@@ -2840,16 +2807,10 @@ class QuicStream extends Duplex {
28402807
const err = handle.shutdown(req);
28412808
if (err === 1)
28422809
return cb();
2810+
// TODO (fix): else if (err !== 0)?
28432811
}
28442812

28452813
_read(nread) {
2846-
if (this.pending)
2847-
return this.once('ready', () => this._read(nread));
2848-
2849-
if (this.destroyed) { // TODO(addaleax): Can this happen?
2850-
this.push(null);
2851-
return;
2852-
}
28532814
if (!this.#didRead) {
28542815
this._readableState.readingMore = false;
28552816
this.#didRead = true;
@@ -2895,6 +2856,7 @@ class QuicStream extends Duplex {
28952856
throw new ERR_INVALID_ARG_TYPE('fd', ['number', 'FileHandle'], fd);
28962857

28972858
if (this.pending) {
2859+
// TODO: This will deadlock on failure?
28982860
return this.once('ready', () => {
28992861
this.sendFD(fd, { offset, length }, ownsFd);
29002862
});

0 commit comments

Comments
 (0)