Skip to content

Commit 9ad097b

Browse files
quic: fix wake up blob
The quic implementation calls setWakeUp with the assumption, that it is only executed once per event loop cycle. This assumption is wrong. Only setImmediate will guarantee, that the execution is delayed to later in the event loop and happening once in the event loop. Fixes: #64035 Signed-off-by: Marten Richter <marten.richter@freenet.de> PR-URL: #64044 Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent c55fa12 commit 9ad097b

1 file changed

Lines changed: 15 additions & 4 deletions

File tree

lib/internal/blob.js

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -475,9 +475,13 @@ function createBlobReaderStream(reader) {
475475
this.pendingPulls = [];
476476
// Lazily register a wakeup callback that the C++ side can invoke
477477
// when new data is available after a STATUS_BLOCK.
478+
let immediate;
478479
this.wakeup = () => {
479480
if (this.pendingPulls.length > 0) {
480-
this.readNext(c);
481+
immediate ??= setImmediate(() => {
482+
immediate = undefined;
483+
this.readNext(c);
484+
});
481485
}
482486
};
483487
},
@@ -577,7 +581,15 @@ const kMaxBatchChunks = 16;
577581
async function* createBlobReaderIterable(reader, options = kEmptyObject) {
578582
const { getReadError } = options;
579583
let wakeup = PromiseWithResolvers();
580-
reader.setWakeup(wakeup.resolve);
584+
let immediate;
585+
let fin = false;
586+
reader.setWakeup((setfin) => {
587+
fin ||= setfin;
588+
immediate ??= setImmediate(() => {
589+
immediate = undefined;
590+
wakeup.resolve?.();
591+
});
592+
});
581593

582594
try {
583595
while (true) {
@@ -622,9 +634,8 @@ async function* createBlobReaderIterable(reader, options = kEmptyObject) {
622634
if (error) throw error;
623635

624636
if (blocked) {
625-
const fin = await wakeup.promise;
637+
await wakeup.promise;
626638
wakeup = PromiseWithResolvers();
627-
reader.setWakeup(wakeup.resolve);
628639
// If the wakeup was triggered by FIN (EndReadable), the DataQueue
629640
// is capped. Continue the loop to pull again -- the next pull will
630641
// return EOS. Without this, a race between the data notification

0 commit comments

Comments
 (0)