1
0
Fork 0
mirror of https://github.com/mozilla/pdf.js.git synced 2025-04-19 22:58:07 +02:00

Avoid using the global workerPort when destruction has started, but not yet finished (issue 16777)

Given that the `PDFDocumentLoadingTask.destroy()`-method is documented as being asynchronous, you thus need to await its completion before attempting to load a new PDF document when using the global `workerPort`.
If you don't await destruction as intended then a new `getDocument`-call can remain pending indefinitely, without any kind of indication of the problem, as shown in the issue.

In order to improve the current situation, without unnecessarily complicating the API-implementation, we'll now throw during the `getDocument`-call if the global `workerPort` is in the process of being destroyed.
This part of the code-base has apparently never been covered by any tests, hence the patch adds unit-tests for both the *correct* usage (awaiting destruction) as well as the specific case outlined in the issue.
This commit is contained in:
Jonas Jenwald 2023-08-12 18:27:01 +02:00
parent 690b873897
commit 66437917db
2 changed files with 90 additions and 7 deletions

View file

@ -898,6 +898,70 @@ describe("api", function () {
});
});
describe("GlobalWorkerOptions", function () {
let savedGlobalWorkerPort;
beforeAll(function () {
savedGlobalWorkerPort = GlobalWorkerOptions.workerPort;
});
afterAll(function () {
GlobalWorkerOptions.workerPort = savedGlobalWorkerPort;
});
it("use global `workerPort` with multiple, sequential, documents", async function () {
if (isNodeJS) {
pending("Worker is not supported in Node.js.");
}
GlobalWorkerOptions.workerPort = new Worker(
new URL("../../build/generic/build/pdf.worker.js", window.location)
);
const loadingTask1 = getDocument(basicApiGetDocumentParams);
const pdfDoc1 = await loadingTask1.promise;
expect(pdfDoc1.numPages).toEqual(3);
await loadingTask1.destroy();
const loadingTask2 = getDocument(
buildGetDocumentParams("tracemonkey.pdf")
);
const pdfDoc2 = await loadingTask2.promise;
expect(pdfDoc2.numPages).toEqual(14);
await loadingTask2.destroy();
});
it(
"avoid using the global `workerPort` when destruction has started, " +
"but not yet finished (issue 16777)",
async function () {
if (isNodeJS) {
pending("Worker is not supported in Node.js.");
}
GlobalWorkerOptions.workerPort = new Worker(
new URL("../../build/generic/build/pdf.worker.js", window.location)
);
const loadingTask = getDocument(basicApiGetDocumentParams);
const pdfDoc = await loadingTask.promise;
expect(pdfDoc.numPages).toEqual(3);
const destroyPromise = loadingTask.destroy();
expect(function () {
getDocument(buildGetDocumentParams("tracemonkey.pdf"));
}).toThrow(
new Error(
"PDFWorker.fromPort - the worker is being destroyed.\n" +
"Please remember to await `PDFDocumentLoadingTask.destroy()`-calls."
)
);
await destroyPromise;
}
);
});
describe("PDFDocument", function () {
let pdfLoadingTask, pdfDocument;