mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-10-02 21:33:52 +02:00
Fix read worker abort bugs (fixes #197)
This commit is contained in:
+30
-6
@@ -234,11 +234,19 @@ export class BlobSource extends Source {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (worker.aborted) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
this.onread?.(worker.currentPos, worker.currentPos + value.length);
|
this.onread?.(worker.currentPos, worker.currentPos + value.length);
|
||||||
this._orchestrator.supplyWorkerData(worker, value);
|
this._orchestrator.supplyWorkerData(worker, value);
|
||||||
} else {
|
} else {
|
||||||
const data = await this._blob.slice(worker.currentPos, worker.targetPos).arrayBuffer();
|
const data = await this._blob.slice(worker.currentPos, worker.targetPos).arrayBuffer();
|
||||||
|
|
||||||
|
if (worker.aborted) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
this.onread?.(worker.currentPos, worker.currentPos + data.byteLength);
|
this.onread?.(worker.currentPos, worker.currentPos + data.byteLength);
|
||||||
this._orchestrator.supplyWorkerData(worker, new Uint8Array(data));
|
this._orchestrator.supplyWorkerData(worker, new Uint8Array(data));
|
||||||
}
|
}
|
||||||
@@ -457,7 +465,7 @@ export class UrlSource extends Source {
|
|||||||
/** @internal */
|
/** @internal */
|
||||||
private async _runWorker(worker: ReadWorker) {
|
private async _runWorker(worker: ReadWorker) {
|
||||||
// The outer loop is for resuming a request if it dies mid-response
|
// The outer loop is for resuming a request if it dies mid-response
|
||||||
while (!worker.aborted) {
|
while (true) {
|
||||||
const existing = this._existingResponses.get(worker);
|
const existing = this._existingResponses.get(worker);
|
||||||
this._existingResponses.delete(worker);
|
this._existingResponses.delete(worker);
|
||||||
|
|
||||||
@@ -534,6 +542,10 @@ export class UrlSource extends Source {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (worker.aborted) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
const { done, value } = readResult;
|
const { done, value } = readResult;
|
||||||
|
|
||||||
if (done) {
|
if (done) {
|
||||||
@@ -552,6 +564,10 @@ export class UrlSource extends Source {
|
|||||||
this.onread?.(worker.currentPos, worker.currentPos + value.length);
|
this.onread?.(worker.currentPos, worker.currentPos + value.length);
|
||||||
this._orchestrator.supplyWorkerData(worker, value);
|
this._orchestrator.supplyWorkerData(worker, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (worker.aborted) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
worker.running = false;
|
worker.running = false;
|
||||||
@@ -796,6 +812,10 @@ export class StreamSource extends Source {
|
|||||||
let data = this._options.read(worker.currentPos, originalTargetPos);
|
let data = this._options.read(worker.currentPos, originalTargetPos);
|
||||||
if (data instanceof Promise) data = await data;
|
if (data instanceof Promise) data = await data;
|
||||||
|
|
||||||
|
if (worker.aborted) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (data instanceof Uint8Array) {
|
if (data instanceof Uint8Array) {
|
||||||
data = toUint8Array(data); // Normalize things like Node.js Buffer to Uint8Array
|
data = toUint8Array(data); // Normalize things like Node.js Buffer to Uint8Array
|
||||||
|
|
||||||
@@ -833,6 +853,10 @@ export class StreamSource extends Source {
|
|||||||
throw new TypeError('ReadableStream returned by options.read must yield Uint8Array chunks.');
|
throw new TypeError('ReadableStream returned by options.read must yield Uint8Array chunks.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (worker.aborted) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
const data = toUint8Array(value); // Normalize things like Node.js Buffer to Uint8Array
|
const data = toUint8Array(value); // Normalize things like Node.js Buffer to Uint8Array
|
||||||
|
|
||||||
this.onread?.(worker.currentPos, worker.currentPos + data.length);
|
this.onread?.(worker.currentPos, worker.currentPos + data.length);
|
||||||
@@ -1420,7 +1444,10 @@ class ReadOrchestrator {
|
|||||||
currentPos: startPos,
|
currentPos: startPos,
|
||||||
targetPos,
|
targetPos,
|
||||||
running: false,
|
running: false,
|
||||||
aborted: false,
|
// Due to async shenanigans, it can happen that workers are started after disposal. In this case, instead of
|
||||||
|
// simply not creating the worker, we allow it to run but immediately label it as aborted, so it can then
|
||||||
|
// shut itself down.
|
||||||
|
aborted: this.disposed,
|
||||||
pendingSlices: [],
|
pendingSlices: [],
|
||||||
age: this.nextAge++,
|
age: this.nextAge++,
|
||||||
};
|
};
|
||||||
@@ -1473,10 +1500,7 @@ class ReadOrchestrator {
|
|||||||
|
|
||||||
/** Called by a worker when it has read some data. */
|
/** Called by a worker when it has read some data. */
|
||||||
supplyWorkerData(worker: ReadWorker, bytes: Uint8Array) {
|
supplyWorkerData(worker: ReadWorker, bytes: Uint8Array) {
|
||||||
if (this.disposed) {
|
assert(!worker.aborted);
|
||||||
// Writes may still come in after disposal, but we just ignore those
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const start = worker.currentPos;
|
const start = worker.currentPos;
|
||||||
const end = start + bytes.length;
|
const end = start + bytes.length;
|
||||||
|
|||||||
Reference in New Issue
Block a user