Zero-copy transfer buffers from the worker to the main thread
This commit is contained in:
parent
c73b4536be
commit
625c6ea4b3
12
src/util.js
12
src/util.js
|
@ -52,19 +52,19 @@ export default {
|
||||||
* @param {Object} obj the options object to be passed to the web worker
|
* @param {Object} obj the options object to be passed to the web worker
|
||||||
* @returns {Array<ArrayBuffer>} an array of binary data to be passed
|
* @returns {Array<ArrayBuffer>} an array of binary data to be passed
|
||||||
*/
|
*/
|
||||||
getTransferables: function(obj) {
|
getTransferables: function(obj, zero_copy) {
|
||||||
const transferables = [];
|
const transferables = [];
|
||||||
util.collectTransferables(obj, transferables);
|
util.collectTransferables(obj, transferables, zero_copy);
|
||||||
return transferables.length ? transferables : undefined;
|
return transferables.length ? transferables : undefined;
|
||||||
},
|
},
|
||||||
|
|
||||||
collectTransferables: function(obj, collection) {
|
collectTransferables: function(obj, collection, zero_copy) {
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (util.isUint8Array(obj) && collection.indexOf(obj.buffer) === -1) {
|
if (util.isUint8Array(obj)) {
|
||||||
if (config.zero_copy) {
|
if (zero_copy && collection.indexOf(obj.buffer) === -1) {
|
||||||
collection.push(obj.buffer);
|
collection.push(obj.buffer);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -91,7 +91,7 @@ export default {
|
||||||
if (Object.prototype.toString.call(value) === '[object MessagePort]') {
|
if (Object.prototype.toString.call(value) === '[object MessagePort]') {
|
||||||
throw new Error("Can't transfer the same stream twice.");
|
throw new Error("Can't transfer the same stream twice.");
|
||||||
}
|
}
|
||||||
util.collectTransferables(value, collection);
|
util.collectTransferables(value, collection, zero_copy);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -22,12 +22,14 @@
|
||||||
* @see module:openpgp.destroyWorker
|
* @see module:openpgp.destroyWorker
|
||||||
* @see module:worker/worker
|
* @see module:worker/worker
|
||||||
* @requires util
|
* @requires util
|
||||||
|
* @requires config
|
||||||
* @requires crypto
|
* @requires crypto
|
||||||
* @requires packet
|
* @requires packet
|
||||||
* @module worker/async_proxy
|
* @module worker/async_proxy
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import util from '../util.js';
|
import util from '../util.js';
|
||||||
|
import config from '../config';
|
||||||
import crypto from '../crypto';
|
import crypto from '../crypto';
|
||||||
import packet from '../packet';
|
import packet from '../packet';
|
||||||
|
|
||||||
|
@ -112,7 +114,7 @@ AsyncProxy.prototype.getID = function() {
|
||||||
*/
|
*/
|
||||||
AsyncProxy.prototype.seedRandom = async function(workerId, size) {
|
AsyncProxy.prototype.seedRandom = async function(workerId, size) {
|
||||||
const buf = await crypto.random.getRandomBytes(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) => {
|
return new Promise((resolve, reject) => {
|
||||||
// clone packets (for web worker structured cloning algorithm)
|
// 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++;
|
this.workers[workerId].requests++;
|
||||||
|
|
||||||
// remember to handle parsing cloned packets from worker
|
// remember to handle parsing cloned packets from worker
|
||||||
|
|
|
@ -133,5 +133,5 @@ function delegate(id, method, options) {
|
||||||
* @param {Object} event Contains event type and data
|
* @param {Object} event Contains event type and data
|
||||||
*/
|
*/
|
||||||
function response(event) {
|
function response(event) {
|
||||||
self.postMessage(event, openpgp.util.getTransferables(event.data));
|
self.postMessage(event, openpgp.util.getTransferables(event.data, true));
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,7 +117,6 @@ describe('Util unit tests', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getTransferables', function() {
|
describe('getTransferables', function() {
|
||||||
let zero_copyVal;
|
|
||||||
const buf1 = new Uint8Array(1);
|
const buf1 = new Uint8Array(1);
|
||||||
const buf2 = new Uint8Array(1);
|
const buf2 = new Uint8Array(1);
|
||||||
const obj = {
|
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() {
|
it('should return undefined when zero_copy is false', function() {
|
||||||
openpgp.config.zero_copy = false;
|
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() {
|
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() {
|
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() {
|
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]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user