From 625c6ea4b3f432964dd29336fdd7faf73703de0f Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Wed, 9 Jan 2019 15:05:16 +0100 Subject: [PATCH] Zero-copy transfer buffers from the worker to the main thread --- src/util.js | 12 ++++++------ src/worker/async_proxy.js | 6 ++++-- src/worker/worker.js | 2 +- test/general/util.js | 18 ++++-------------- 4 files changed, 15 insertions(+), 23 deletions(-) diff --git a/src/util.js b/src/util.js index 9953781d..a526d5e0 100644 --- a/src/util.js +++ b/src/util.js @@ -52,19 +52,19 @@ export default { * @param {Object} obj the options object to be passed to the web worker * @returns {Array} an array of binary data to be passed */ - getTransferables: function(obj) { + getTransferables: function(obj, zero_copy) { const transferables = []; - util.collectTransferables(obj, transferables); + util.collectTransferables(obj, transferables, zero_copy); return transferables.length ? transferables : undefined; }, - collectTransferables: function(obj, collection) { + collectTransferables: function(obj, collection, zero_copy) { if (!obj) { return; } - if (util.isUint8Array(obj) && collection.indexOf(obj.buffer) === -1) { - if (config.zero_copy) { + if (util.isUint8Array(obj)) { + if (zero_copy && collection.indexOf(obj.buffer) === -1) { collection.push(obj.buffer); } return; @@ -91,7 +91,7 @@ export default { if (Object.prototype.toString.call(value) === '[object MessagePort]') { throw new Error("Can't transfer the same stream twice."); } - util.collectTransferables(value, collection); + util.collectTransferables(value, collection, zero_copy); }); } }, diff --git a/src/worker/async_proxy.js b/src/worker/async_proxy.js index 7576c836..35ed6990 100644 --- a/src/worker/async_proxy.js +++ b/src/worker/async_proxy.js @@ -22,12 +22,14 @@ * @see module:openpgp.destroyWorker * @see module:worker/worker * @requires util + * @requires config * @requires crypto * @requires packet * @module worker/async_proxy */ import util from '../util.js'; +import config from '../config'; import crypto from '../crypto'; import packet from '../packet'; @@ -112,7 +114,7 @@ AsyncProxy.prototype.getID = function() { */ AsyncProxy.prototype.seedRandom = async function(workerId, size) { const buf = await crypto.random.getRandomBytes(size); - this.workers[workerId].postMessage({ event:'seed-random', buf }, util.getTransferables(buf)); + this.workers[workerId].postMessage({ event:'seed-random', buf }, util.getTransferables(buf, true)); }; /** @@ -145,7 +147,7 @@ AsyncProxy.prototype.delegate = function(method, options) { return new Promise((resolve, reject) => { // clone packets (for web worker structured cloning algorithm) - this.workers[workerId].postMessage({ id:id, event:method, options:packet.clone.clonePackets(options) }, util.getTransferables(options)); + this.workers[workerId].postMessage({ id:id, event:method, options:packet.clone.clonePackets(options) }, util.getTransferables(options, config.zero_copy)); this.workers[workerId].requests++; // remember to handle parsing cloned packets from worker diff --git a/src/worker/worker.js b/src/worker/worker.js index 69df6096..845b1a6b 100644 --- a/src/worker/worker.js +++ b/src/worker/worker.js @@ -133,5 +133,5 @@ function delegate(id, method, options) { * @param {Object} event Contains event type and data */ function response(event) { - self.postMessage(event, openpgp.util.getTransferables(event.data)); + self.postMessage(event, openpgp.util.getTransferables(event.data, true)); } diff --git a/test/general/util.js b/test/general/util.js index 32b672c4..e9162659 100644 --- a/test/general/util.js +++ b/test/general/util.js @@ -117,7 +117,6 @@ describe('Util unit tests', function() { }); describe('getTransferables', function() { - let zero_copyVal; const buf1 = new Uint8Array(1); const buf2 = new Uint8Array(1); const obj = { @@ -128,27 +127,18 @@ describe('Util unit tests', function() { } }; - beforeEach(function() { - zero_copyVal = openpgp.config.zero_copy; - openpgp.config.zero_copy = true; - }); - - afterEach(function() { - openpgp.config.zero_copy = zero_copyVal; - }); - it('should return undefined when zero_copy is false', function() { openpgp.config.zero_copy = false; - expect(openpgp.util.getTransferables(obj)).to.be.undefined; + expect(openpgp.util.getTransferables(obj, false)).to.be.undefined; }); it('should return undefined for no input', function() { - expect(openpgp.util.getTransferables()).to.be.undefined; + expect(openpgp.util.getTransferables(undefined, true)).to.be.undefined; }); it('should return undefined for an empty oject', function() { - expect(openpgp.util.getTransferables({})).to.be.undefined; + expect(openpgp.util.getTransferables({}, true)).to.be.undefined; }); it('should return two buffers', function() { - expect(openpgp.util.getTransferables(obj)).to.deep.equal([buf1.buffer, buf2.buffer]); + expect(openpgp.util.getTransferables(obj, true)).to.deep.equal([buf1.buffer, buf2.buffer]); }); });