From 6f22327e6166ccf92f8131b55591df177feef686 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Fri, 19 Nov 2021 13:51:18 +0100 Subject: [PATCH] [api-minor] Only use Workers when `postMessage` transfers are supported (PR 11123 follow-up) Given that all modern browsers now support `postMessage` transfers, and have for years, it no longer seems necessary for the PDF.js library to support using Workers unless the `postMessage` transfers functionality is available. This patch is a follow-up to PR 11123, which made it impossible to *manually* disable `postMessage` transfers for performance reasons (since it increases memory usage), which hasn't caused any bug reports as far as I know.[1] Hence we'll now only support *proper* Worker implementations, with fully working `postMessage` transfers, and fallback to using "fake" Workers otherwise. --- [1] At the time of that PR we still "supported" IE, which is why this code was left intact. --- src/core/worker.js | 17 +++-------------- src/display/api.js | 10 ++-------- src/shared/message_handler.js | 23 ++++------------------- 3 files changed, 9 insertions(+), 41 deletions(-) diff --git a/src/core/worker.js b/src/core/worker.js index 96443a8f5..c981bd5f1 100644 --- a/src/core/worker.js +++ b/src/core/worker.js @@ -75,16 +75,9 @@ class WorkerMessageHandler { } testMessageProcessed = true; - // check if Uint8Array can be sent to worker - if (!(data instanceof Uint8Array)) { - handler.send("test", null); - return; - } - // making sure postMessage transfers are working - const supportTransfers = data[0] === 255; - handler.postMessageTransfers = supportTransfers; - - handler.send("test", { supportTransfers }); + // Ensure that `TypedArray`s can be sent to the worker, + // and that `postMessage` transfers are supported. + handler.send("test", data instanceof Uint8Array && data[0] === 255); }); handler.on("configure", function wphConfigure(data) { @@ -156,10 +149,6 @@ class WorkerMessageHandler { const workerHandlerName = docParams.docId + "_worker"; let handler = new MessageHandler(workerHandlerName, docId, port); - // Ensure that postMessage transfers are always correctly enabled/disabled, - // to prevent "DataCloneError" in browsers without transfers support. - handler.postMessageTransfers = docParams.postMessageTransfers; - function ensureNotTerminated() { if (terminated) { throw new Error("Worker was terminated"); diff --git a/src/display/api.js b/src/display/api.js index b3a7fdc95..92c80dfe0 100644 --- a/src/display/api.js +++ b/src/display/api.js @@ -439,7 +439,6 @@ function getDocument(src) { workerId, worker.port ); - messageHandler.postMessageTransfers = worker.postMessageTransfers; const transport = new WorkerTransport( messageHandler, task, @@ -498,7 +497,6 @@ async function _fetchDocument(worker, source, pdfDataRangeTransport, docId) { }, maxImageSize: source.maxImageSize, disableFontFace: source.disableFontFace, - postMessageTransfers: worker.postMessageTransfers, docBaseUrl: source.docBaseUrl, ignoreErrors: source.ignoreErrors, isEvalSupported: source.isEvalSupported, @@ -2079,7 +2077,6 @@ class PDFWorker { this.name = name; this.destroyed = false; - this.postMessageTransfers = true; this.verbosity = verbosity; this._readyCapability = createPromiseCapability(); @@ -2188,13 +2185,10 @@ class PDFWorker { return; // worker was destroyed } if (data) { - // supportTypedArray this._messageHandler = messageHandler; this._port = worker; this._webWorker = worker; - if (!data.supportTransfers) { - this.postMessageTransfers = false; - } + this._readyCapability.resolve(); // Send global setting, e.g. verbosity level. messageHandler.send("configure", { @@ -2222,7 +2216,7 @@ class PDFWorker { }); const sendTest = () => { - const testObj = new Uint8Array([this.postMessageTransfers ? 255 : 0]); + const testObj = new Uint8Array([255]); // Some versions of Opera throw a DATA_CLONE_ERR on serializing the // typed array. Also, checking if we can use transfers. try { diff --git a/src/shared/message_handler.js b/src/shared/message_handler.js index 660fbb266..15d73b9ce 100644 --- a/src/shared/message_handler.js +++ b/src/shared/message_handler.js @@ -83,7 +83,6 @@ class MessageHandler { this.comObj = comObj; this.callbackId = 1; this.streamId = 1; - this.postMessageTransfers = true; this.streamSinks = Object.create(null); this.streamControllers = Object.create(null); this.callbackCapabilities = Object.create(null); @@ -180,7 +179,7 @@ class MessageHandler { * @param {Array} [transfers] - List of transfers/ArrayBuffers. */ send(actionName, data, transfers) { - this._postMessage( + this.comObj.postMessage( { sourceName: this.sourceName, targetName: this.targetName, @@ -204,7 +203,7 @@ class MessageHandler { const capability = createPromiseCapability(); this.callbackCapabilities[callbackId] = capability; try { - this._postMessage( + this.comObj.postMessage( { sourceName: this.sourceName, targetName: this.targetName, @@ -247,7 +246,7 @@ class MessageHandler { cancelCall: null, isClosed: false, }; - this._postMessage( + comObj.postMessage( { sourceName, targetName, @@ -322,7 +321,7 @@ class MessageHandler { this.sinkCapability = createPromiseCapability(); this.ready = this.sinkCapability.promise; } - self._postMessage( + comObj.postMessage( { sourceName, targetName, @@ -549,20 +548,6 @@ class MessageHandler { delete this.streamControllers[streamId]; } - /** - * Sends raw message to the comObj. - * @param {Object} message - Raw message. - * @param transfers List of transfers/ArrayBuffers, or undefined. - * @private - */ - _postMessage(message, transfers) { - if (transfers && this.postMessageTransfers) { - this.comObj.postMessage(message, transfers); - } else { - this.comObj.postMessage(message); - } - } - destroy() { this.comObj.removeEventListener("message", this._onComObjOnMessage); }